diff --git a/OAT.xml b/OAT.xml index c72788ac93f6427d06e8ad04814670b7add779d5..5e58f52dc8d25a68d4cd0c28556751f815656115 100644 --- a/OAT.xml +++ b/OAT.xml @@ -73,6 +73,15 @@ + + + + + + + + + diff --git a/ohos/test_cached_network_image/.gitignore b/ohos/test_cached_network_image/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_cached_network_image/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_cached_network_image/.metadata b/ohos/test_cached_network_image/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..c64177774df6a3ceb0f67e70374ac42f58b6bccb --- /dev/null +++ b/ohos/test_cached_network_image/.metadata @@ -0,0 +1,45 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_cached_network_image/README.md b/ohos/test_cached_network_image/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/analysis_options.yaml b/ohos/test_cached_network_image/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_cached_network_image/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_cached_network_image/lib/common/base_page.dart b/ohos/test_cached_network_image/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..987585c34978cebd1560dbba1ff3f5fb542512ef --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/base_page.dart @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_cached_network_image/lib/common/item_widget.dart b/ohos/test_cached_network_image/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..2f6c380665461e81d7085bfae36e837c2c552a85 --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/item_widget.dart @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_cached_network_image/lib/common/main_item_widget.dart b/ohos/test_cached_network_image/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c49255738e5a7c8d934dd6813ffd853e960c839c --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/main_item_widget.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_cached_network_image/lib/common/test_model_app.dart b/ohos/test_cached_network_image/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..045851633e9cad7d8ff09f2836930125c71216ee --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/test_model_app.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_cached_network_image/lib/common/test_page.dart b/ohos/test_cached_network_image/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_cached_network_image/lib/common/test_route.dart b/ohos/test_cached_network_image/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_cached_network_image/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_cached_network_image/lib/main.dart b/ohos/test_cached_network_image/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..6fc64661a1bd78fa4cba554c730a5af1222d0af5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/main.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:test_cached_network_image/src/fix_bug.dart'; +import 'package:test_cached_network_image/src/image_cache_manager_test.dart'; +import 'package:test_cached_network_image/src/image_provider_test.dart'; +import 'package:test_cached_network_image/src/image_stream_completer_test.dart'; +import 'package:test_cached_network_image/src/image_widget_test.dart'; +import 'package:test_cached_network_image/src/ui_apge.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + HttpOverrides.global = GlobalHttpOverrides(); + final app = [ + // MainItem('仅测试使用', FixBug()), + MainItem('演示包含[CachedNetworkImage]的[StatelessWidget]', BasicContent()), + MainItem('演示包含[CachedNetworkImage]的[ListView]', ListContent()), + MainItem('演示包含[CachedNetworkImage]的[GridView]', GridContent()), + MainItem('CachedNetworkImage', ImageWidgetTestPage('CachedNetworkImage')), + MainItem('MultiImageStreamCompleter', ImageStreamCompleterTestPage('MultiImageStreamCompleter')), + MainItem('CachedNetworkImageProvider', ImageProviderTestPage('CachedNetworkImageProvider')), + MainItem('ImageCacheManager', ImageCacheManagerTestPage('ImageCacheManager')), + ]; + + runApp(TestModelApp(appName: 'CachedNetworkImage', data: app)); +} + +class GlobalHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + // TODO: implement createHttpClient + return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/CHANGELOG.md b/ohos/test_cached_network_image/lib/path_provider-2.0.0/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/README.md b/ohos/test_cached_network_image/lib/path_provider-2.0.0/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/build.gradle b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..9659efbc03d27a916d09b72494bb6005c66f516d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/build.gradle @@ -0,0 +1,46 @@ +group 'io.flutter.plugins.pathprovider' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 29 + + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } + android { + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + } +} + +dependencies { + implementation 'androidx.annotation:annotation:1.1.0' + implementation 'com.google.guava:guava:28.1-android' + testImplementation 'junit:junit:4.12' +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/gradle.properties b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..8bd86f6805108dec87d0be823bdb1384bec8aa19 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/settings.gradle b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..71bc90768477fb1e2bd5a2535dec5531c3986580 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'path_provider' diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..abb2584adcb41e98809f390a23233ea51a2530ec --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml @@ -0,0 +1,17 @@ + + + diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..902811dcb367ae535230ce67b6b69f83a5126b79 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.flutter.plugins.pathprovider; + +import android.content.Context; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Handler; +import android.os.Looper; +import androidx.annotation.NonNull; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.SettableFuture; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.util.PathUtils; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class PathProviderPlugin implements FlutterPlugin, MethodCallHandler { + + private Context context; + private MethodChannel channel; + private final Executor uiThreadExecutor = new UiThreadExecutor(); + private final Executor executor = + Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder() + .setNameFormat("path-provider-background-%d") + .setPriority(Thread.NORM_PRIORITY) + .build()); + + public PathProviderPlugin() {} + + @SuppressWarnings("deprecation") + public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + PathProviderPlugin instance = new PathProviderPlugin(); + instance.channel = new MethodChannel(registrar.messenger(), "plugins.flutter.io/path_provider"); + instance.context = registrar.context(); + instance.channel.setMethodCallHandler(instance); + } + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + channel = new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/path_provider"); + context = binding.getApplicationContext(); + channel.setMethodCallHandler(this); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + channel = null; + } + + private void executeInBackground(Callable task, Result result) { + final SettableFuture future = SettableFuture.create(); + Futures.addCallback( + future, + new FutureCallback() { + public void onSuccess(T answer) { + result.success(answer); + } + + public void onFailure(Throwable t) { + result.error(t.getClass().getName(), t.getMessage(), null); + } + }, + uiThreadExecutor); + executor.execute( + () -> { + try { + future.set(task.call()); + } catch (Throwable t) { + future.setException(t); + } + }); + } + + @Override + public void onMethodCall(MethodCall call, @NonNull Result result) { + switch (call.method) { + case "getTemporaryDirectory": + executeInBackground(() -> getPathProviderTemporaryDirectory(), result); + break; + case "getApplicationDocumentsDirectory": + executeInBackground(() -> getPathProviderApplicationDocumentsDirectory(), result); + break; + case "getStorageDirectory": + executeInBackground(() -> getPathProviderStorageDirectory(), result); + break; + case "getExternalCacheDirectories": + executeInBackground(() -> getPathProviderExternalCacheDirectories(), result); + break; + case "getExternalStorageDirectories": + final Integer type = call.argument("type"); + final String directoryName = StorageDirectoryMapper.androidType(type); + executeInBackground(() -> getPathProviderExternalStorageDirectories(directoryName), result); + break; + case "getApplicationSupportDirectory": + executeInBackground(() -> getApplicationSupportDirectory(), result); + break; + default: + result.notImplemented(); + } + } + + private String getPathProviderTemporaryDirectory() { + return context.getCacheDir().getPath(); + } + + private String getApplicationSupportDirectory() { + return PathUtils.getFilesDir(context); + } + + private String getPathProviderApplicationDocumentsDirectory() { + return PathUtils.getDataDirectory(context); + } + + private String getPathProviderStorageDirectory() { + final File dir = context.getExternalFilesDir(null); + if (dir == null) { + return null; + } + return dir.getAbsolutePath(); + } + + private List getPathProviderExternalCacheDirectories() { + final List paths = new ArrayList<>(); + + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + for (File dir : context.getExternalCacheDirs()) { + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + } else { + File dir = context.getExternalCacheDir(); + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + + return paths; + } + + private List getPathProviderExternalStorageDirectories(String type) { + final List paths = new ArrayList<>(); + + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + for (File dir : context.getExternalFilesDirs(type)) { + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + } else { + File dir = context.getExternalFilesDir(type); + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + + return paths; + } + + private static class UiThreadExecutor implements Executor { + private final Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void execute(Runnable command) { + handler.post(command); + } + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..23459294300e4f91eeee552804b29f454c12716c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.flutter.plugins.pathprovider; + +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Environment; + +/** Helps to map the Dart `StorageDirectory` enum to a Android system constant. */ +class StorageDirectoryMapper { + + /** + * Return a Android Environment constant for a Dart Index. + * + * @return The correct Android Environment constant or null, if the index is null. + * @throws IllegalArgumentException If `dartIndex` is not null but also not matches any known + * index. + */ + static String androidType(Integer dartIndex) throws IllegalArgumentException { + if (dartIndex == null) { + return null; + } + + switch (dartIndex) { + case 0: + return Environment.DIRECTORY_MUSIC; + case 1: + return Environment.DIRECTORY_PODCASTS; + case 2: + return Environment.DIRECTORY_RINGTONES; + case 3: + return Environment.DIRECTORY_ALARMS; + case 4: + return Environment.DIRECTORY_NOTIFICATIONS; + case 5: + return Environment.DIRECTORY_PICTURES; + case 6: + return Environment.DIRECTORY_MOVIES; + case 7: + return Environment.DIRECTORY_DOWNLOADS; + case 8: + return Environment.DIRECTORY_DCIM; + case 9: + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + return Environment.DIRECTORY_DOCUMENTS; + } else { + throw new IllegalArgumentException("Documents directory is unsupported."); + } + default: + throw new IllegalArgumentException("Unknown index: " + dartIndex); + } + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..da9346003964a3aa8f353e76b7eda0bf3d09c811 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.flutter.plugins.pathprovider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import android.os.Environment; +import org.junit.Test; + +public class StorageDirectoryMapperTest { + + @org.junit.Test + public void testAndroidType_null() { + assertNull(StorageDirectoryMapper.androidType(null)); + } + + @org.junit.Test + public void testAndroidType_valid() { + assertEquals(Environment.DIRECTORY_MUSIC, StorageDirectoryMapper.androidType(0)); + assertEquals(Environment.DIRECTORY_PODCASTS, StorageDirectoryMapper.androidType(1)); + assertEquals(Environment.DIRECTORY_RINGTONES, StorageDirectoryMapper.androidType(2)); + assertEquals(Environment.DIRECTORY_ALARMS, StorageDirectoryMapper.androidType(3)); + assertEquals(Environment.DIRECTORY_NOTIFICATIONS, StorageDirectoryMapper.androidType(4)); + assertEquals(Environment.DIRECTORY_PICTURES, StorageDirectoryMapper.androidType(5)); + assertEquals(Environment.DIRECTORY_MOVIES, StorageDirectoryMapper.androidType(6)); + assertEquals(Environment.DIRECTORY_DOWNLOADS, StorageDirectoryMapper.androidType(7)); + assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(8)); + } + + @Test + public void testAndroidType_invalid() { + try { + assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(10)); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unknown index: " + 10, e.getMessage()); + } + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Assets/.gitkeep b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Assets/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..b63a08259bcae8b0abcebb13e94555e3ec57a07c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h @@ -0,0 +1,19 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#import + +@interface FLTPathProviderPlugin : NSObject +@end diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m new file mode 100644 index 0000000000000000000000000000000000000000..ad7097b3bcd72438cbabec652ebd91752343451e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +#import "FLTPathProviderPlugin.h" + +NSString* GetDirectoryOfType(NSSearchPathDirectory dir) { + NSArray* paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES); + return paths.firstObject; +} + +static FlutterError* getFlutterError(NSError* error) { + if (error == nil) return nil; + return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %ld", (long)error.code] + message:error.domain + details:error.localizedDescription]; +} + +@implementation FLTPathProviderPlugin + ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = + [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/path_provider" + binaryMessenger:registrar.messenger]; + [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + if ([@"getTemporaryDirectory" isEqualToString:call.method]) { + result([self getTemporaryDirectory]); + } else if ([@"getApplicationDocumentsDirectory" isEqualToString:call.method]) { + result([self getApplicationDocumentsDirectory]); + } else if ([@"getApplicationSupportDirectory" isEqualToString:call.method]) { + NSString* path = [self getApplicationSupportDirectory]; + + // Create the path if it doesn't exist + NSError* error; + NSFileManager* fileManager = [NSFileManager defaultManager]; + BOOL success = [fileManager createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (!success) { + result(getFlutterError(error)); + } else { + result(path); + } + } else if ([@"getLibraryDirectory" isEqualToString:call.method]) { + result([self getLibraryDirectory]); + } else { + result(FlutterMethodNotImplemented); + } + }]; +} + ++ (NSString*)getTemporaryDirectory { + return GetDirectoryOfType(NSCachesDirectory); +} + ++ (NSString*)getApplicationDocumentsDirectory { + return GetDirectoryOfType(NSDocumentDirectory); +} + ++ (NSString*)getApplicationSupportDirectory { + return GetDirectoryOfType(NSApplicationSupportDirectory); +} + ++ (NSString*)getLibraryDirectory { + return GetDirectoryOfType(NSLibraryDirectory); +} + +@end diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/path_provider.podspec b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/path_provider.podspec new file mode 100644 index 0000000000000000000000000000000000000000..151d755273485f33e74efefec3a30e5b53424891 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/ios/path_provider.podspec @@ -0,0 +1,38 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'path_provider' + s.version = '0.0.1' + s.summary = 'Flutter Path Provider' + s.description = <<-DESC +A Flutter plugin for getting commonly used locations on the filesystem. +Downloaded by pub (not CocoaPods). + DESC + s.homepage = 'https://github.com/flutter/plugins' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider' } + s.documentation_url = 'https://pub.dev/packages/path_provider' + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } +end + diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/lib/path_provider.dart b/ohos/test_cached_network_image/lib/path_provider-2.0.0/lib/path_provider.dart new file mode 100644 index 0000000000000000000000000000000000000000..0a6b944993323ab0c7a94ca2251f58a973e23117 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/lib/path_provider.dart @@ -0,0 +1,233 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:io' show Directory, Platform; + +import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting; +import 'package:path_provider_linux/path_provider_linux.dart'; +import 'package:path_provider_windows/path_provider_windows.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; + +export 'package:path_provider_platform_interface/path_provider_platform_interface.dart' + show StorageDirectory; + +@visibleForTesting +@Deprecated('This is no longer necessary, and is now a no-op') +set disablePathProviderPlatformOverride(bool override) {} + +bool _manualDartRegistrationNeeded = true; + +/// An exception thrown when a directory that should always be available on +/// the current platform cannot be obtained. +class MissingPlatformDirectoryException implements Exception { + /// Creates a new exception + MissingPlatformDirectoryException(this.message, {this.details}); + + /// The explanation of the exception. + final String message; + + /// Added details, if any. + /// + /// E.g., an error object from the platform implementation. + final Object? details; + + @override + String toString() { + String detailsAddition = details == null ? '' : ': $details'; + return 'MissingPlatformDirectoryException($message)$detailsAddition'; + } +} + +PathProviderPlatform get _platform { + // This is to manually endorse Dart implementations until automatic + // registration of Dart plugins is implemented. For details see + // https://github.com/flutter/flutter/issues/52267. + if (_manualDartRegistrationNeeded) { + // Only do the initial registration if it hasn't already been overridden + // with a non-default instance. + if (!kIsWeb && PathProviderPlatform.instance is MethodChannelPathProvider) { + if (Platform.isLinux) { + PathProviderPlatform.instance = PathProviderLinux(); + } else if (Platform.isWindows) { + PathProviderPlatform.instance = PathProviderWindows(); + } + } + _manualDartRegistrationNeeded = false; + } + + return PathProviderPlatform.instance; +} + +/// Path to the temporary directory on the device that is not backed up and is +/// suitable for storing caches of downloaded files. +/// +/// Files in this directory may be cleared at any time. This does *not* return +/// a new temporary directory. Instead, the caller is responsible for creating +/// (and cleaning up) files or directories within this directory. This +/// directory is scoped to the calling application. +/// +/// On iOS, this uses the `NSCachesDirectory` API. +/// +/// On Android, this uses the `getCacheDir` API on the context. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getTemporaryDirectory() async { + final String? path = await _platform.getTemporaryPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get temporary directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may place application support +/// files. +/// +/// Use this for files you don’t want exposed to the user. Your app should not +/// use this directory for user data files. +/// +/// On iOS, this uses the `NSApplicationSupportDirectory` API. +/// If this directory does not exist, it is created automatically. +/// +/// On Android, this function uses the `getFilesDir` API on the context. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationSupportDirectory() async { + final String? path = await _platform.getApplicationSupportPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get application support directory'); + } + + return Directory(path); +} + +/// Path to the directory where application can store files that are persistent, +/// backed up, and not visible to the user, such as sqlite.db. +/// +/// On Android, this function throws an [UnsupportedError] as no equivalent +/// path exists. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory on a supported platform. +Future getLibraryDirectory() async { + final String? path = await _platform.getLibraryPath(); + if (path == null) { + throw MissingPlatformDirectoryException('Unable to get library directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may place data that is +/// user-generated, or that cannot otherwise be recreated by your application. +/// +/// On iOS, this uses the `NSDocumentDirectory` API. Consider using +/// [getApplicationSupportDirectory] instead if the data is not user-generated. +/// +/// On Android, this uses the `getDataDirectory` API on the context. Consider +/// using [getExternalStorageDirectory] instead if data is intended to be visible +/// to the user. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationDocumentsDirectory() async { + final String? path = await _platform.getApplicationDocumentsPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get application documents directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may access top level storage. +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an [UnsupportedError] as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this uses the `getExternalFilesDir(null)`. +Future getExternalStorageDirectory() async { + final String? path = await _platform.getExternalStoragePath(); + if (path == null) { + return null; + } + return Directory(path); +} + +/// Paths to directories where application specific external cache data can be +/// stored. These paths typically reside on external storage like separate +/// partitions or SD cards. Phones may have multiple storage directories +/// available. +/// +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an UnsupportedError as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this returns Context.getExternalCacheDirs() or +/// Context.getExternalCacheDir() on API levels below 19. +Future?> getExternalCacheDirectories() async { + final List? paths = await _platform.getExternalCachePaths(); + if (paths == null) { + return null; + } + + return paths.map((String path) => Directory(path)).toList(); +} + +/// Paths to directories where application specific data can be stored. +/// These paths typically reside on external storage like separate partitions +/// or SD cards. Phones may have multiple storage directories available. +/// +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an UnsupportedError as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this returns Context.getExternalFilesDirs(String type) or +/// Context.getExternalFilesDir(String type) on API levels below 19. +Future?> getExternalStorageDirectories({ + /// Optional parameter. See [StorageDirectory] for more informations on + /// how this type translates to Android storage directories. + StorageDirectory? type, +}) async { + final List? paths = + await _platform.getExternalStoragePaths(type: type); + if (paths == null) { + return null; + } + + return paths.map((String path) => Directory(path)).toList(); +} + +/// Path to the directory where downloaded files can be stored. +/// This is typically only relevant on desktop operating systems. +/// +/// On Android and on iOS, this function throws an [UnsupportedError] as no equivalent +/// path exists. +Future getDownloadsDirectory() async { + final String? path = await _platform.getDownloadsPath(); + if (path == null) { + return null; + } + return Directory(path); +} diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/macos/path_provider.podspec b/ohos/test_cached_network_image/lib/path_provider-2.0.0/macos/path_provider.podspec new file mode 100644 index 0000000000000000000000000000000000000000..176e2c983e3f9072f687367860ae0bc11d3335ea --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/macos/path_provider.podspec @@ -0,0 +1,37 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'path_provider' + s.version = '0.0.1' + s.summary = 'No-op implementation of the macos path_provider to avoid build issues on macos' + s.description = <<-DESC + No-op implementation of the path_provider plugin to avoid build issues on macos. + https://github.com/flutter/flutter/issues/46618 + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/path_provider' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + + s.platform = :osx + s.osx.deployment_target = '10.11' +end + diff --git a/ohos/test_cached_network_image/lib/path_provider-2.0.0/pubspec.yaml b/ohos/test_cached_network_image/lib/path_provider-2.0.0/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3ae3b3ffb7d262900ad4ec78281f1651827972ae --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider-2.0.0/pubspec.yaml @@ -0,0 +1,61 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: path_provider +description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. +homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider +version: 2.0.0 +publish_to: none + +flutter: + plugin: + platforms: + android: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + ios: + pluginClass: FLTPathProviderPlugin + macos: + default_package: path_provider_ohos + linux: + default_package: path_provider_ohos + windows: + default_package: path_provider_ohos + ohos: + default_package: path_provider_ohos + +dependencies: + flutter: + sdk: flutter + path_provider_platform_interface: ^2.0.0 + path_provider_macos: ^2.0.0 + path_provider_linux: ^2.0.0 + path_provider_windows: ^2.0.0 + path_provider_ohos: + path: ../path_provider_ohos +dev_dependencies: +# integration_test: +# path: ../../integration_test + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + pedantic: ^1.10.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + test: ^1.16.0 + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/AUTHORS b/ohos/test_cached_network_image/lib/path_provider_ohos/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..d6a0ebb6ce1ec5f6713344bf177684cd0372cccf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/AUTHORS @@ -0,0 +1,81 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/CHANGELOG.md b/ohos/test_cached_network_image/lib/path_provider_ohos/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/README.md b/ohos/test_cached_network_image/lib/path_provider_ohos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/lib/messages.g.dart b/ohos/test_cached_network_image/lib/path_provider_ohos/lib/messages.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..b605273a022fb8c4768686a24a1d5cde5d9aab2b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/lib/messages.g.dart @@ -0,0 +1,204 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum StorageDirectory { + root, + music, + podcasts, + ringtones, + alarms, + notifications, + pictures, + movies, + downloads, + dcim, + documents, +} + +class PathProviderApi { + /// Constructor for [PathProviderApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + PathProviderApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getTemporaryPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationSupportPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationDocumentsPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationCachePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getExternalStoragePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future> getExternalCachePaths() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getExternalStoragePaths( + StorageDirectory arg_directory) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_directory.index]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/lib/path_provider_ohos.dart b/ohos/test_cached_network_image/lib/path_provider_ohos/lib/path_provider_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..62a2051832acae8667740e017065b3c4c9bde545 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/lib/path_provider_ohos.dart @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'messages.g.dart' as messages; + +messages.StorageDirectory _convertStorageDirectory( + StorageDirectory? directory) { + switch (directory) { + case null: + return messages.StorageDirectory.root; + case StorageDirectory.music: + return messages.StorageDirectory.music; + case StorageDirectory.podcasts: + return messages.StorageDirectory.podcasts; + case StorageDirectory.ringtones: + return messages.StorageDirectory.ringtones; + case StorageDirectory.alarms: + return messages.StorageDirectory.alarms; + case StorageDirectory.notifications: + return messages.StorageDirectory.notifications; + case StorageDirectory.pictures: + return messages.StorageDirectory.pictures; + case StorageDirectory.movies: + return messages.StorageDirectory.movies; + case StorageDirectory.downloads: + return messages.StorageDirectory.downloads; + case StorageDirectory.dcim: + return messages.StorageDirectory.dcim; + case StorageDirectory.documents: + return messages.StorageDirectory.documents; + } +} + +/// The OHOS implementation of [PathProviderPlatform]. +class PathProviderOhos extends PathProviderPlatform { + final messages.PathProviderApi _api = messages.PathProviderApi(); + + /// Registers this class as the default instance of [PathProviderPlatform]. + static void registerWith() { + PathProviderPlatform.instance = PathProviderOhos(); + } + + @override + Future getTemporaryPath() { + return _api.getTemporaryPath(); + } + + @override + Future getApplicationSupportPath() { + return _api.getApplicationSupportPath(); + } + + @override + Future getLibraryPath() { + throw UnsupportedError('getLibraryPath is not supported on OHOS'); + } + + @override + Future getApplicationDocumentsPath() { + return _api.getApplicationDocumentsPath(); + } + + @override + Future getApplicationCachePath() { + return _api.getApplicationCachePath(); + } + + @override + Future getExternalStoragePath() { + return _api.getExternalStoragePath(); + } + + @override + Future?> getExternalCachePaths() async { + return (await _api.getExternalCachePaths()).cast(); + } + + @override + Future?> getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) + .cast(); + } + + @override + Future getDownloadsPath() { + throw UnsupportedError('getDownloadsPath is not supported on OHOS'); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..1e922e7e1fc28adb088df43e96d59e2e64598bf0 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json @@ -0,0 +1 @@ +{"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5":{"hashValue":"c5cbb5522de13fac82f033c7cd9b48d8","name":"app.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":226,"lastModifiedTime":1695632211627}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5":{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5":{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json":{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json":{"hashValue":"1c8e8a915a9b7f222d4cf94722d1bb42","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":491,"lastModifiedTime":1698044664928}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json":{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs":{"hashValue":"fb414dab48788ac59123df55cae63f0b","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"2a8cdcb7a112ce8f608fa4c5a8b26644","name":"flutter_ohos.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs\\flutter_ohos.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":19163432,"lastModifiedTime":1698044260416}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default":{"hashValue":"","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default","type":"directory","isSymbolicLink":false,"children":[]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources":{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default":{"hashValue":"76f5c8d078ca69ae9175830aa99a05dc","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f12d653569ed3cffc2c73dbcf141b3e7","name":"ids_map","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"fde1d32f9d3798179b3345d3d3b044a8","name":"id_defined.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":148,"lastModifiedTime":1698044665019}}]},{"hashValue":"2ed40cf3b6a0258fcf7ef0d5663211d7","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":652,"lastModifiedTime":1698044665018}},{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},{"hashValue":"98c2ba5b20a7da7409087b816f0988e8","name":"resources.index","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources.index","type":"file","isSymbolicLink":false,"fileMetaData":{"size":396,"lastModifiedTime":1698044665018}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h":{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default":{"hashValue":"93721c69ae9a43a6b6b026ce4ba28ad2","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default":{"hashValue":"de5eea44e80e5ff634766ec94c928117","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider":{"hashValue":"7190fb2c4d706ed6e0e4babda37414da","name":"path_provider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"dd38cfe42b111fd0bc58052c7bc17c51","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3a65d298f5e72b2d44c536dcdc681eab","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt":{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar":{"hashValue":"77ec3ff3075d1e1b0f77eea3593fc54a","name":"default@PackageHar","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"34bdaa94e55567ca04e39d0ddc512301","name":"build-profile.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\build-profile.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":119,"lastModifiedTime":1695632211630}},{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\libs","type":"directory","isSymbolicLink":false,"children":[]},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},{"hashValue":"ae45559de2480bc70d782647539c87a9","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d1732197995c7f8e834be72e56bec866","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default":{"hashValue":"876919e92069ce600cf972b0875777f7","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"7505492774406aa9fff80dba7d7feac7","name":"path_provider.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default\\path_provider.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":3760,"lastModifiedTime":1698044665105}}]}} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..c424f579e9642bd97516da860942f4f330a46bc7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json @@ -0,0 +1 @@ +{":ohos:path_provider:default@PreBuild":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"apiType\",\"_value\":\"stageMode\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"codeType\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"customTypes\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceType\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isSupportOhpmProj\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"profileModuleName\",\"_value\":\"path_provider\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"sdkToolchainsComponentVersion\",\"_value\":\"4.0.0.40\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetStatusCode\",\"_value\":2,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PreBuild","_key":":ohos:path_provider:default@PreBuild","_executionId":":ohos:path_provider:default@PreBuild:1698044664739","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"isDirectory":false,"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"isDirectory":false,"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5",{"fileSnapShotHashValue":"c55207f83ac823903369a4a9dab86116"}]]},"_outputFiles":{"dataType":"Map","value":[]}},":ohos:path_provider:default@MergeProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"asanEnable\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"buildRoot\",\"_value\":\"build\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isDebug\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isHarModule\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"multiProjects\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"releaseType\",\"_value\":\"Release\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@MergeProfile","_key":":ohos:path_provider:default@MergeProfile","_executionId":":ohos:path_provider:default@MergeProfile:1698044664825","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]}},":ohos:path_provider:default@ProcessProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"arkEnable\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileMode\",\"_value\":\"esmodule\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceTypes\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"dependency\",\"_value\":\"[]\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessProfile","_key":":ohos:path_provider:default@ProcessProfile","_executionId":":ohos:path_provider:default@ProcessProfile:1698044664829","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}]]}},":ohos:path_provider:default@ProcessResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"resConfigJsonContent\",\"_value\":\"{\\\"configPath\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\process_profile\\\\\\\\default\\\\\\\\module.json\\\",\\\"packageName\\\":\\\"io.flutter.plugins.pathprovider\\\",\\\"output\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\",\\\"moduleNames\\\":\\\"path_provider\\\",\\\"ResourceTable\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\generated\\\\\\\\r\\\\\\\\default\\\\\\\\ResourceTable.h\\\"],\\\"moduleResources\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\src\\\\\\\\main\\\\\\\\resources\\\"],\\\"dependencies\\\":[],\\\"ids\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\",\\\"definedIds\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\\\\\\id_defined.json\\\"}\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessResource","_key":":ohos:path_provider:default@ProcessResource","_executionId":":ohos:path_provider:default@ProcessResource:1697686151230","_inputFiles":{"dataType":"Map","value":[]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]}},":ohos:path_provider:default@ProcessLibs":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessLibs","_key":":ohos:path_provider:default@ProcessLibs","_executionId":":ohos:path_provider:default@ProcessLibs:1698044664930","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs",{"isDirectory":true,"fileSnapShotHashValue":"fb414dab48788ac59123df55cae63f0b"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}]]}},":ohos:path_provider:default@CompileResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"TARGET_CONFIG\",\"_value\":\"{\\\"name\\\":\\\"default\\\"}\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe,-l,D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\intermediates\\\\res\\\\default\\\\resConfig.json\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@CompileResource","_key":":ohos:path_provider:default@CompileResource","_executionId":":ohos:path_provider:default@CompileResource:1698044664937","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources",{"fileSnapShotHashValue":"c8b0c1d9d5adf5ad1facbc15311568c7"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"isDirectory":false,"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default",{"isDirectory":true,"fileSnapShotHashValue":"76f5c8d078ca69ae9175830aa99a05dc"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h",{"isDirectory":false,"fileSnapShotHashValue":"d021dd9a3167074553dba4f2c5854465"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default",{"isDirectory":true,"fileSnapShotHashValue":"93721c69ae9a43a6b6b026ce4ba28ad2"}]]}},":ohos:path_provider:default@PackageHar":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"hasNativeOption\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"needCppTypes\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"harModuleJson\",\"_value\":\"D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar\\\\src\\\\main\\\\module.json5\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isOhpmProject\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"artifactType\",\"_value\":\"original\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"C:\\\\Users\\\\z30010942\\\\nodejs\\\\npm.cmd,pack\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"cwd:D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar;\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PackageHar","_key":":ohos:path_provider:default@PackageHar","_executionId":":ohos:path_provider:default@PackageHar:1698044665025","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default",{"isDirectory":true,"fileSnapShotHashValue":"de5eea44e80e5ff634766ec94c928117"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider",{"isDirectory":true,"test":{"dataType":"RegExp","value":"^(?!D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\libs|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\node_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\oh_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.cxx|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.previewer|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.hvigor|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.gitignore|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.ohpmignore).*"},"fileSnapShotHashValue":"7190fb2c4d706ed6e0e4babda37414da"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt",{"isDirectory":false,"fileSnapShotHashValue":"94cde23849d24d7b4c50116f9d63d725"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar",{"isDirectory":true,"fileSnapShotHashValue":"77ec3ff3075d1e1b0f77eea3593fc54a"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default",{"isDirectory":true,"fileSnapShotHashValue":"876919e92069ce600cf972b0875777f7"}]]}}} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json new file mode 100644 index 0000000000000000000000000000000000000000..e55e21ac77968038ea81d662bea7ef034aa7b14b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json @@ -0,0 +1,16 @@ +{ + "totalTime": 481506500, + "moduleNum": 1, + "taskTime": { + "compileArkTS": 0, + "buildArkTS": 0, + "compileJS": 0, + "buildJS": 0, + "compileResource": 0, + "packageHap": 0, + "signHap": 0 + }, + "isIncremental": true, + "hasIncremental": false, + "isParallel": true +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json new file mode 100644 index 0000000000000000000000000000000000000000..ca06e5bb15cfd13c1535a1a9f14d0141af5ebbf3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json @@ -0,0 +1,39 @@ +{ + "ohos-module-path_provider": { + "SELECT_TARGET": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build", + "TARGETS": { + "default": { + "SOURCE_ROOT": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main", + "RESOURCES_PATH": [ + "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources" + ], + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates", + "JS_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", + "WORKER_LOADER": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json" + }, + "BUILD_OPTION": { + "debuggable": true + } + } + } + }, + "ohos-project": { + "SELECT_PRODUCT_NAME": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build", + "BUNDLE_NAME": "io.flutter.plugins.pathprovider", + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build\\outputs\\default" + } + }, + "version": 1 +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json new file mode 100644 index 0000000000000000000000000000000000000000..c812c2d046ee61ce12cbc028f21d33e82ac413a1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json @@ -0,0 +1,31 @@ +{ + "version": "1.0", + "workerIdList": [ + -1 + ], + "metrics": [ + { + "type": "build_line", + "endTime": 1699407048308, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "path_provider", + "workerId": -1, + "startTime": 1699407048307 + }, + { + "type": "build_line", + "endTime": 1699407048309, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "ohos", + "workerId": -1, + "startTime": 1699407048309 + } + ], + "workLog": [] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/app.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..68d6882c192e3684e2e9e50a05846b4839fff894 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..553ced4f7ebe2ed3fca66c4ef9637ce3ad65d12e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "path_provider" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/build-profile.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5c1e5d53d93e28d421dca80f583fc79b3f2ef772 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.cer", + "storePassword": "0000001A14E9D3E5C4DF2ED15CED1A37B72F435E8D176F43E415FF2213D4C9C753FA62E51E4621A952A5", + "keyAlias": "debugKey", + "keyPassword": "0000001AC6F51F5DA12538489C8E00F23C111099A8622DA17D8D6B2FE7A456D4D2D21C903D3DEB198EC9", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "path_provider", + "srcPath": "./path_provider" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..71e363a4f754b90a3153a9f2e98c7d27ce776978 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..ce46aa6fa02c8e8e049a7e85ee0b3d708046567d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorfile.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..de76d0675bc13811fab0d07317942dc5efef4b54 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..2a70dc127d52200fc4b276b00ca6b7caa239bc62 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw @@ -0,0 +1,63 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw.bat b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..9c0bce666c29dcc3ef35dae78c7be9cafa1267ae --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/hvigorw.bat @@ -0,0 +1,79 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/local.properties b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..864e8480e5edabc3faccd6c365441bf21a0d27da --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/local.properties @@ -0,0 +1,9 @@ +# This file is automatically generated by DevEco Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file should *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# For customization when using a Version Control System, please read the header note. +nodejs.dir=C:/Users/hched/node/node-16.20.1 +hwsdk.dir=C:/Users/hched/AppData/Local/Huawei/Sdk \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8117ee588b7b4e9899feee78e294b5fbb14fbc3f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..541f70556af34058c8eb3256c62730cfd762d214 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/CHANGELOG.md b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/README.md b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.d.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..b0b4394a3284c07e873e84c9144cd31889e1863d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.d.ts @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +export const DEFAULT = 0B0000 + +export const when: when; + +export enum TestType { + FUNCTION = 0B1, + PERFORMANCE = 0B1 << 1, + POWER = 0B1 << 2, + RELIABILITY = 0B1 << 3, + SECURITY = 0B1 << 4, + GLOBAL = 0B1 << 5, + COMPATIBILITY = 0B1 << 6, + USER = 0B1 << 7, + STANDARD = 0B1 << 8, + SAFETY = 0B1 << 9, + RESILIENCE = 0B1 << 10 +} + +export enum Size { + SMALLTEST = 0B1 << 16, + MEDIUMTEST = 0B1 << 17, + LARGETEST = 0B1 << 18 +} + +export enum Level { + LEVEL0 = 0B1 << 24, + LEVEL1 = 0B1 << 25, + LEVEL2 = 0B1 << 26, + LEVEL3 = 0B1 << 27, + LEVEL4 = 0B1 << 28 +} + +export function describe(testSuiteName: string, callback: Function): void + +export function beforeEach(callback: Function): void + +export function afterEach(callback: Function): void + +export function beforeAll(callback: Function): void + +export function afterAll(callback: Function): void + +export function it(testCaseName: string, attribute: (TestType | Size | Level), callback: Function) + +export interface Assert { + assertClose(expectValue: number, precision: number): void + assertContain(expectValue: any): void + assertEqual(expectValue: any): void + assertFail(): void + assertFalse(): void + assertTrue(): void + assertInstanceOf(expectValue: string): void + assertLarger(expectValue: number): void + assertLess(expectValue: number): void + assertNull(): void + assertThrowError(expectValue: string): void + assertUndefined(): void + assertLargerOrEqual(expectValue: number):void + assertLessOrEqual(expectValue: number):void + assertNaN():void + assertNegUnlimited(): void + assertPosUnlimited(): void + not(): Assert; + assertDeepEquals(expectValue: any):void + assertPromiseIsPending(): void + assertPromiseIsRejected(): void + assertPromiseIsRejectedWith(expectValue?: any): void + assertPromiseIsRejectedWithError(...expectValue): void + assertPromiseIsResolved(): void + assertPromiseIsResolvedWith(expectValue?: any): void +} + +export function expect(actualValue?: any): Assert + +export class ArgumentMatchers { + static any; + static anyString; + static anyBoolean; + static anyNumber; + static anyObj; + static anyFunction; + static matchRegexs(Regex: RegExp): void +} + +declare interface when { + afterReturn(value: any): any + afterReturnNothing(): undefined + afterAction(action: any): any + afterThrow(e_msg: string): string + (argMatchers?: any): when; +} + +export interface VerificationMode { + times(count: Number): void + never(): void + once(): void + atLeast(count: Number): void + atMost(count: Number): void +} + +export class MockKit { + constructor() + mockFunc(obj: Object, func: Function): Function + mockObject(obj: Object): Object + verify(methodName: String, argsArray: Array): VerificationMode + ignoreMock(obj: Object, func: Function): void + clear(obj: Object): void + clearAll(): void +} + +export class SysTestKit { + static actionStart(tag: string): void + static actionEnd(tag: string): void + static existKeyword(keyword: string, timeout?: number): boolean +} + +export class Hypium { + static setData(data: {[key: string]: any}): void + static setTimeConfig(systemTime: any) + static hypiumTest(abilityDelegator: any, abilityDelegatorArguments: any, testsuite: Function): void +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c3fe31746bcc2d00e4f8b33e67be5c5a26f9d22 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.ets @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Core from './src/main/core'; +import {DEFAULT, TestType, Size, Level} from './src/main/Constant'; +import DataDriver from './src/main/module/config/DataDriver'; +import ExpectExtend from './src/main/module/assert/ExpectExtend'; +import OhReport from './src/main/module/report/OhReport'; +import SysTestKit from './src/main/module/kit/SysTestKit'; +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface'; +import {MockKit, when} from './src/main/module/mock/MockKit'; +import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers'; + +class Hypium { + static setData(data) { + const core = Core.getInstance(); + const dataDriver = new DataDriver({data}); + core.addService('dataDriver', dataDriver); + } + + static setTimeConfig(systemTime) { + SysTestKit.systemTime = systemTime; + } + + static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) { + const core = Core.getInstance(); + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }); + core.addService('expect', expectExtend); + const ohReport = new OhReport({ + 'delegator': abilityDelegator, + 'abilityDelegatorArguments': abilityDelegatorArguments + }); + SysTestKit.delegator = abilityDelegator; + core.addService('report', ohReport); + core.init(); + core.subscribeEvent('spec', ohReport); + core.subscribeEvent('suite', ohReport); + core.subscribeEvent('task', ohReport); + const configService = core.getDefaultService('config'); + + let testParameters = {}; + if (abilityDelegatorArguments !== null) { + testParameters = configService.translateParams(abilityDelegatorArguments.parameters); + } + console.info('parameters:' + JSON.stringify(testParameters)); + configService.setConfig(testParameters); + + testsuite(); + if (Object.prototype.hasOwnProperty.call(globalThis, 'setupUiTestEnvironment')) { + globalThis.setupUiTestEnvironment().then(() => { + console.info('UiTestKit::after run uitest setup, start run testcases'); + core.execute(abilityDelegator); + }).catch((error) => { + console.error('UiTestKit:: call setupUiTestEnvironment failure:' + error); + core.execute(abilityDelegator); + }); + } else { + console.info('UiTestKit:: no need to setup uitest, start run testcases'); + core.execute(abilityDelegator); + } + } +} + +export { + Hypium, + Core, + DEFAULT, + TestType, + Size, + Level, + DataDriver, + ExpectExtend, + OhReport, + SysTestKit, + describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, + MockKit, when, + ArgumentMatchers +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js new file mode 100644 index 0000000000000000000000000000000000000000..3c3fe31746bcc2d00e4f8b33e67be5c5a26f9d22 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/index.js @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Core from './src/main/core'; +import {DEFAULT, TestType, Size, Level} from './src/main/Constant'; +import DataDriver from './src/main/module/config/DataDriver'; +import ExpectExtend from './src/main/module/assert/ExpectExtend'; +import OhReport from './src/main/module/report/OhReport'; +import SysTestKit from './src/main/module/kit/SysTestKit'; +import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect} from './src/main/interface'; +import {MockKit, when} from './src/main/module/mock/MockKit'; +import ArgumentMatchers from './src/main/module/mock/ArgumentMatchers'; + +class Hypium { + static setData(data) { + const core = Core.getInstance(); + const dataDriver = new DataDriver({data}); + core.addService('dataDriver', dataDriver); + } + + static setTimeConfig(systemTime) { + SysTestKit.systemTime = systemTime; + } + + static hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) { + const core = Core.getInstance(); + const expectExtend = new ExpectExtend({ + 'id': 'extend' + }); + core.addService('expect', expectExtend); + const ohReport = new OhReport({ + 'delegator': abilityDelegator, + 'abilityDelegatorArguments': abilityDelegatorArguments + }); + SysTestKit.delegator = abilityDelegator; + core.addService('report', ohReport); + core.init(); + core.subscribeEvent('spec', ohReport); + core.subscribeEvent('suite', ohReport); + core.subscribeEvent('task', ohReport); + const configService = core.getDefaultService('config'); + + let testParameters = {}; + if (abilityDelegatorArguments !== null) { + testParameters = configService.translateParams(abilityDelegatorArguments.parameters); + } + console.info('parameters:' + JSON.stringify(testParameters)); + configService.setConfig(testParameters); + + testsuite(); + if (Object.prototype.hasOwnProperty.call(globalThis, 'setupUiTestEnvironment')) { + globalThis.setupUiTestEnvironment().then(() => { + console.info('UiTestKit::after run uitest setup, start run testcases'); + core.execute(abilityDelegator); + }).catch((error) => { + console.error('UiTestKit:: call setupUiTestEnvironment failure:' + error); + core.execute(abilityDelegator); + }); + } else { + console.info('UiTestKit:: no need to setup uitest, start run testcases'); + core.execute(abilityDelegator); + } + } +} + +export { + Hypium, + Core, + DEFAULT, + TestType, + Size, + Level, + DataDriver, + ExpectExtend, + OhReport, + SysTestKit, + describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, + MockKit, when, + ArgumentMatchers +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..74b3beaa21ce731c12319a495381b9ec9297c751 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/oh-package.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "name": "@ohos/hypium", + "version": "1.0.6", + "description": "A unit test framework for OpenHarmony application", + "main": "index.js", + "keywords": [], + "author": "huawei", + "license": "Apache-2.0", + "dependencies": { + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js new file mode 100644 index 0000000000000000000000000000000000000000..f1829107720a64df7b571a4bfd11a25e6d9022b6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/Constant.js @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** + * define the testcase type : TestType, Size , Level + */ +export const DEFAULT = 0B0000; + +export class TestType { + static FUNCTION = 0B1; + static PERFORMANCE = 0B1 << 1; + static POWER = 0B1 << 2; + static RELIABILITY = 0B1 << 3; + static SECURITY = 0B1 << 4; + static GLOBAL = 0B1 << 5; + static COMPATIBILITY = 0B1 << 6; + static USER = 0B1 << 7; + static STANDARD = 0B1 << 8; + static SAFETY = 0B1 << 9; + static RESILIENCE = 0B1 << 10; +} + +export class Size { + static SMALLTEST = 0B1 << 16; + static MEDIUMTEST = 0B1 << 17; + static LARGETEST = 0B1 << 18; +} + +export class Level { + static LEVEL0 = 0B1 << 24; + static LEVEL1 = 0B1 << 25; + static LEVEL2 = 0B1 << 26; + static LEVEL3 = 0B1 << 27; + static LEVEL4 = 0B1 << 28; +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/core.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/core.js new file mode 100644 index 0000000000000000000000000000000000000000..cfcb5f17287208f5e6869b4248faf6c9093002d9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/core.js @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {SuiteService, SpecService, ExpectService, ReportService} from './service'; +import {ConfigService} from './module/config/configService'; +import {SpecEvent, TaskEvent, SuiteEvent} from './event'; + +/** + * core service for execute testcase. + */ +class Core { + static getInstance() { + if (!this.instance) { + this.instance = new Core(); + } + return this.instance; + } + + constructor() { + this.instance = null; + this.services = { + suite: {}, + spec: {}, + config: {}, + expect: {}, + log: {}, + report: {} + + }; + this.events = { + suite: {}, + spec: {}, + task: {} + }; + } + + addService(name, service) { + let serviceObj = {}; + if (!this.services[name]) { + this.services[name] = serviceObj; + } else { + serviceObj = this.services[name]; + } + serviceObj[service.id] = service; + } + + getDefaultService(name) { + return this.services[name].default; + } + + getServices(name) { + return this.services[name]; + } + + registerEvent(serviceName, event) { + let eventObj = {}; + if (!this.events[serviceName]) { + this.events[serviceName] = eventObj; + } else { + eventObj = this.events[serviceName]; + } + eventObj[event.id] = event; + } + + unRegisterEvent(serviceName, eventID) { + const eventObj = this.events[serviceName]; + if (eventObj) { + delete eventObj[eventID]; + } + } + + subscribeEvent(serviceName, serviceObj) { + const eventObj = this.events[serviceName]; + if (eventObj) { + for (const attr in eventObj) { + eventObj[attr]['subscribeEvent'](serviceObj); + } + } + } + + async fireEvents(serviceName, eventName) { + const eventObj = this.events[serviceName]; + if (!eventObj) { + return; + } + for (const attr in eventObj) { + await eventObj[attr][eventName](); + } + } + + addToGlobal(apis) { + if (typeof globalThis !== 'undefined') { + for (let api in apis) { + globalThis[api] = apis[api]; + } + } + for (const api in apis) { + this[api] = apis[api]; + } + } + + init() { + this.addService('suite', new SuiteService({id: 'default'})); + this.addService('spec', new SpecService({id: 'default'})); + this.addService('expect', new ExpectService({id: 'default'})); + this.addService('report', new ReportService({id: 'default'})); + this.addService('config', new ConfigService({id: 'default'})); + this.registerEvent('task', new TaskEvent({id: 'default', coreContext: this})); + this.registerEvent('suite', new SuiteEvent({id: 'default', coreContext: this})); + this.registerEvent('spec', new SpecEvent({id: 'default', coreContext: this})); + this.subscribeEvent('spec', this.getDefaultService('report')); + this.subscribeEvent('suite', this.getDefaultService('report')); + this.subscribeEvent('task', this.getDefaultService('report')); + const context = this; + for (const key in this.services) { + const serviceObj = this.services[key]; + for (const serviceID in serviceObj) { + const service = serviceObj[serviceID]; + service.init(context); + + if (typeof service.apis !== 'function') { + continue; + } + const apis = service.apis(); + if (apis) { + this.addToGlobal(apis); + } + } + } + } + + execute(abilityDelegator) { + const suiteService = this.getDefaultService('suite'); + const configService = this.getDefaultService('config'); + if (configService['dryRun'] === 'true') { + (async function () { + await suiteService.dryRun(abilityDelegator); + })(); + return; + } + setTimeout(() => { + suiteService.execute(); + }, 10); + } +} + +export default Core; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/event.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/event.js new file mode 100644 index 0000000000000000000000000000000000000000..1333a1c483f9a2aa1c45e133b1d3cbbc7cdb8346 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/event.js @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class SpecEvent { + constructor(attr) { + this.id = attr.id; + this.coreContext = attr.context; + this.eventMonitors = []; + } + + subscribeEvent(service) { + this.eventMonitors.push(service); + } + + async specStart() { + for (const monitor of this.eventMonitors) { + await monitor['specStart'](); + } + } + + async specDone() { + for (const monitor of this.eventMonitors) { + await monitor['specDone'](); + } + } +} + +class SuiteEvent { + constructor(attr) { + this.id = attr.id; + this.suiteContext = attr.coreContext; + this.eventMonitors = []; + } + + subscribeEvent(service) { + this.eventMonitors.push(service); + } + + async suiteStart() { + for (const monitor of this.eventMonitors) { + await monitor['suiteStart'](); + } + } + + async suiteDone() { + for (const monitor of this.eventMonitors) { + await monitor['suiteDone'](); + } + } +} + +class TaskEvent { + constructor(attr) { + this.id = attr.id; + this.coreContext = attr.coreContext; + this.eventMonitors = []; + } + + subscribeEvent(service) { + this.eventMonitors.push(service); + } + + async taskStart() { + for (const monitor of this.eventMonitors) { + await monitor['taskStart'](); + } + } + + async taskDone() { + for (const monitor of this.eventMonitors) { + await monitor['taskDone'](); + } + } + + incorrectFormat() { + for (const monitor of this.eventMonitors) { + monitor['incorrectFormat'](); + } + } +} + +export {SpecEvent, TaskEvent, SuiteEvent}; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/interface.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/interface.js new file mode 100644 index 0000000000000000000000000000000000000000..40398c849d55cd76ab64fcba26899b547e2a3c97 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/interface.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Core from './core'; + +const core = Core.getInstance(); + +const describe = function (desc, func) { + return Reflect.has(core, 'describe') ? core.describe(desc, func) : (desc, func) => { }; +}; +const it = function (desc, filter, func) { + return Reflect.has(core, 'it') ? core.it(desc, filter, func) : (desc, filter, func) => { }; +}; +const beforeEach = function (func) { + return Reflect.has(core, 'beforeEach') ? core.beforeEach(func) : (func) => { }; +}; +const afterEach = function (func) { + return Reflect.has(core, 'afterEach') ? core.afterEach(func) : (func) => { }; +}; +const beforeAll = function (func) { + return Reflect.has(core, 'beforeAll') ? core.beforeAll(func) : (func) => { }; +}; +const afterAll = function (func) { + return Reflect.has(core, 'afterAll') ? core.afterAll(func) : (func) => { }; +}; +const expect = function (actualValue) { + return Reflect.has(core, 'expect') ? core.expect(actualValue) : (actualValue) => { }; +}; + +export { + describe, it, beforeAll, beforeEach, afterEach, afterAll, expect +}; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js new file mode 100644 index 0000000000000000000000000000000000000000..d10d15e6f9955c6d04610101f8766c951ee1a35d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/ExpectExtend.js @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import assertNull from './assertNull'; +import assertClose from './assertClose'; +import assertContain from './assertContain'; +import assertLess from './assertLess'; +import assertLarger from './assertLarger'; +import assertFail from './assertFail'; +import assertUndefined from './assertUndefined'; +import assertFalse from './assertFalse'; +import assertInstanceOf from './assertInstanceOf'; +import assertThrowError from './assertThrowError'; +import assertLargerOrEqual from './assertLargerOrEqual' +import assertLessOrEqual from './assertLessOrEqual' +import assertNaN from './assertNaN' +import assertNegUnlimited from './assertNegUnlimited' +import assertPosUnlimited from './assertPosUnlimited' +import assertDeepEquals from './deepEquals/assertDeepEquals' +import assertPromiseIsPending from './assertPromiseIsPending'; +import assertPromiseIsRejected from './assertPromiseIsRejected'; +import assertPromiseIsRejectedWith from './assertPromiseIsRejectedWith'; +import assertPromiseIsRejectedWithError from './assertPromiseIsRejectedWithError'; +import assertPromiseIsResolved from './assertPromiseIsResolved'; +import assertPromiseIsResolvedWith from './assertPromiseIsResolvedWith'; +class ExpectExtend { + constructor(attr) { + this.id = attr.id; + this.matchers = {}; + } + + extendsMatchers() { + this.matchers.assertNull = assertNull; + this.matchers.assertClose = assertClose; + this.matchers.assertContain = assertContain; + this.matchers.assertLess = assertLess; + this.matchers.assertLarger = assertLarger; + this.matchers.assertFail = assertFail; + this.matchers.assertUndefined = assertUndefined; + this.matchers.assertFalse = assertFalse; + this.matchers.assertInstanceOf = assertInstanceOf; + this.matchers.assertThrowError = assertThrowError; + this.matchers.assertLargerOrEqual = assertLargerOrEqual; + this.matchers.assertLessOrEqual = assertLessOrEqual; + this.matchers.assertNaN = assertNaN; + this.matchers.assertNegUnlimited = assertNegUnlimited; + this.matchers.assertPosUnlimited = assertPosUnlimited; + this.matchers.assertDeepEquals = assertDeepEquals; + this.matchers.assertPromiseIsPending = assertPromiseIsPending; + this.matchers.assertPromiseIsRejected = assertPromiseIsRejected; + this.matchers.assertPromiseIsRejectedWith = assertPromiseIsRejectedWith; + this.matchers.assertPromiseIsRejectedWithError = assertPromiseIsRejectedWithError; + this.matchers.assertPromiseIsResolved = assertPromiseIsResolved; + this.matchers.assertPromiseIsResolvedWith = assertPromiseIsResolvedWith; + } + + init(coreContext) { + this.coreContext = coreContext; + this.extendsMatchers(); + const expectService = this.coreContext.getDefaultService('expect'); + expectService.addMatchers(this.matchers); + } + + apis() { + return { + 'expect': function (actualValue) { + return this.coreContext.getDefaultService('expect').expect(actualValue); + } + }; + } +} + +export default ExpectExtend; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js new file mode 100644 index 0000000000000000000000000000000000000000..63635bea5bf1298776de565260e0e0babae56857 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertClose.js @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertClose(actualValue, expected) { + console.log('expected:' + expected[0] + ',precision:' + expected[1]); + if (actualValue === null && expected[0] === null) { + throw new Error('actualValue and expected can not be both null!!!'); + } + let result; + let diff = Math.abs(expected[0] - actualValue); + let actualAbs = Math.abs(actualValue); + if ((actualAbs - 0) === 0) { + if ((diff - 0) === 0) { + result = true; + } else { + result = false; + } + } else if (diff / actualAbs < expected[1]) { + result = true; + } else { + result = false; + } + return { + pass: result, + message: '|' + actualValue + ' - ' + expected[0] + '|/' + actualValue + ' is not less than ' + expected[1] + }; +} + +export default assertClose; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js new file mode 100644 index 0000000000000000000000000000000000000000..7fba0d9755503e5e926f6c1a4e425e0d1cf47570 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertContain.js @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertContain(actualValue, expect) { + let result = false; + if (Object.prototype.toString.call(actualValue).indexOf('Array')) { + for (let i in actualValue) { + if (actualValue[i] == expect[0]) { + result = true; + } + } + } + let type = Object.prototype.toString.call(actualValue); + if (type === '[object String]') { + result = actualValue.indexOf(expect[0]) >= 0; + } + return { + pass: result, + message: 'expect false, ' + actualValue + ' do not have ' + expect[0] + }; +} + +export default assertContain; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js new file mode 100644 index 0000000000000000000000000000000000000000..8ab4ac5caef712c75c4eac49dfbbb91d33669d9a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFail.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertFail() { + return { + pass: false, + message: 'fail ' + }; +} + +export default assertFail; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js new file mode 100644 index 0000000000000000000000000000000000000000..c5008e94f4b2ce13ed35b604811793c76b542347 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertFalse.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertFalse(actualValue) { + return { + pass: (actualValue) === false, + message: 'expect false, actualValue is ' + actualValue + }; +} + +export default assertFalse; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js new file mode 100644 index 0000000000000000000000000000000000000000..1e11b93f7251c67f5455c5007cd7be268aa53b32 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertInstanceOf.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertInstanceOf(actualValue, expected) { + if (Object.prototype.toString.call(actualValue) == '[object ' + expected[0] + ']') { + return { + pass: true + }; + } else { + return { + pass: false, + message: actualValue + ' is ' + Object.prototype.toString.call(actualValue) + 'not ' + expected[0] + }; + } +} + +export default assertInstanceOf; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js new file mode 100644 index 0000000000000000000000000000000000000000..a74f4a8cedaf3add9c2dc2d3799081a83198732f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLarger.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertLarger(actualValue, expected) { + return { + pass: (actualValue) > expected[0], + message: (actualValue) + ' is not larger than ' + expected[0] + }; +} + +export default assertLarger; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js new file mode 100644 index 0000000000000000000000000000000000000000..e847e6c217364b7f69c173c66fb98d10efc45ef1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLargerOrEqual.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertLargerOrEqual(actualValue, expected) { + return { + pass: (actualValue) >= expected[0], + message: (actualValue) + ' is not larger than ' + expected[0] + }; +} + +export default assertLargerOrEqual; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js new file mode 100644 index 0000000000000000000000000000000000000000..17e84b0abaeb20804048a5a15c19e0603634846d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLess.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertLess(actualValue, expected) { + return { + pass: (actualValue) < expected[0], + message: (actualValue) + ' is not less than ' + expected[0] + }; +} + +export default assertLess; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js new file mode 100644 index 0000000000000000000000000000000000000000..f754f97ffa9d24e7852efe2423a1dd35d448af82 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertLessOrEqual.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertLessOrEqual(actualValue, expected) { + return { + pass: (actualValue) <= expected[0], + message: (actualValue) + ' is not less than ' + expected[0] + }; +} + +export default assertLessOrEqual; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js new file mode 100644 index 0000000000000000000000000000000000000000..8d45d6a93b86c5ed325a68b32ff014835993a58e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNaN.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertNaN(actualValue) { + return { + pass: actualValue !== actualValue, + message: 'expect NaN, actualValue is ' + actualValue + }; +} + +export default assertNaN; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js new file mode 100644 index 0000000000000000000000000000000000000000..ceac555afc826e057970e6cfe9c73b322c672aa2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNegUnlimited.js @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +function assertNegUnlimited(actualValue) { + return { + pass: actualValue === Number.NEGATIVE_INFINITY, + message: 'Expected actualValue not to be -Infinity. actualValue is,' + actualValue + }; +} + +export default assertNegUnlimited; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js new file mode 100644 index 0000000000000000000000000000000000000000..53a7bad827323a98d3302a4e7eea679551b459c5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertNull.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertNull(actualValue) { + return { + pass: (actualValue) === null, + message: 'expect null, actualValue is ' + (actualValue) + }; +} + +export default assertNull; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js new file mode 100644 index 0000000000000000000000000000000000000000..6e68c0e2b6c499f4dc3dd56c13e9ea1073a3c54c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPosUnlimited.js @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2022 Huawei Device Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +function assertPosUnlimited(actualValue) { + return { + pass: actualValue === Number.POSITIVE_INFINITY, + message: 'Expected actualValue is POSITIVE_INFINITY. actualValue is,' + actualValue + }; +} + +export default assertPosUnlimited; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js new file mode 100644 index 0000000000000000000000000000000000000000..7e2ca2ce14d50c39554fc1157d6d4eb9329d5c39 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsPending.js @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsPending(actualPromise) { + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + return helper === got ? {pass: true, message: 'actualValue is isPending'} + : { + pass: false, + message: 'expect isPending, actualValue is resolve' + }; + }, + function () { + return { + pass: false + , message: 'expect isPending, actualValue is reject' + }; + }); +} + +export default assertPromiseIsPending; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js new file mode 100644 index 0000000000000000000000000000000000000000..eb8e65c7d70d5750a9ccebb55c2cf5049cf144fc --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejected.js @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsRejected(actualPromise) { + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + return { + pass: false, + message: 'expect isRejected, but actualValue is ' + + (helper === got ? 'isPending' : 'resolve') + }; + }, + function () { + return {pass: true, message: 'actualValue is isRejected'}; + } + ); +} + +export default assertPromiseIsRejected; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js new file mode 100644 index 0000000000000000000000000000000000000000..48eaf7859279a70ea2ad85509296b5da1c7b69f9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWith.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsRejectedWith(actualPromise, expectedValue) { + + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + + function tips(passed) { + return ('Expected a promise ' + (passed ? 'not ' : '') + + 'to be rejected with ' + JSON.stringify(expectedValue[0])); + } + + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + return { + pass: false, + message: tips(false) + ' but actualValue is ' + + (helper === got ? 'isPending' : 'resolve') + }; + }, + function (actualValue) { + if (JSON.stringify(actualValue) == JSON.stringify(expectedValue[0])) { + return { + pass: true, + message: 'actualValue was rejected with ' + JSON.stringify(actualValue) + '.' + }; + } else { + return { + pass: false, + message: tips(false) + ' but it was rejected with ' + JSON.stringify(actualValue) + '.' + }; + } + } + ); +} + +export default assertPromiseIsRejectedWith; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js new file mode 100644 index 0000000000000000000000000000000000000000..334a3d397fec0a0f79b9aa1bf92a9622b580351f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsRejectedWithError.js @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsRejectedWithError(actualPromise, expectedValue) { + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + return { + pass: false, + message: 'Expected a promise to be rejected but actualValue is ' + + (helper === got ? 'isPending' : 'resolve') + }; + }, + function (actualValue) { + return matchError(actualValue, expectedValue); + } + ); + +} + +function matchError(actualValue, expectedValue) { + if (expectedValue.length == 1 && typeof expectedValue[0] === 'function') { + if (expectedValue[0].name === actualValue.__proto__.name) { + return {pass: true, message: 'actual error type is ' + actualValue.name + '.'}; + } + return { + pass: false, + message: 'except error type is ' + expectedValue[0].name + ',but actual is ' + actualValue.name + '.' + }; + } + + if (expectedValue.length == 1 && typeof expectedValue[0] === 'string') { + if (expectedValue[0] === actualValue.message) { + return {pass: true, message: 'actual error message is ' + actualValue.message + '.'}; + } + return { + pass: false, + message: 'except error message ' + expectedValue[0] + ',but actual is ' + actualValue.message + '.' + }; + } + + if (expectedValue.length == 1) { + return { + pass: false, + message: 'When only one parameter, it ' + + 'should be error type or error message.' + }; + } + + if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name === actualValue.name) { + if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) { + return {pass: true, message: 'actual error message is ' + actualValue.message + '.'}; + } else { + return { + pass: false, + message: 'except error message is ' + expectedValue[1] + ',but actual is ' + actualValue.message + '.' + }; + } + } + + if (expectedValue.length == 2 && typeof expectedValue[0] === 'function' && expectedValue[0].name !== actualValue.name) { + if (typeof expectedValue[1] === 'string' && actualValue.message === expectedValue[1]) { + return { + pass: false, + message: 'except error type is ' + expectedValue[0].name + ',but actual is ' + actualValue.name + '.' + }; + } else { + return { + pass: false, + message: 'except error type and message are incorrect.' + }; + } + } + + if (expectedValue.length > 2) { + return { + pass: false, + message: 'Up to two parameters are supported.' + }; + } +} + +export default assertPromiseIsRejectedWithError; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js new file mode 100644 index 0000000000000000000000000000000000000000..855426ca79e5002428e53d4fcb5f843cdf7119f7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolved.js @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsResolved(actualPromise) { + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + return helper === got ? { + pass: false, + message: 'expect resolve, actualValue is isPending' + } + : {pass: true, message: 'actualValue is isResolved'}; + }, + function (rej) { + return { + pass: false, + message: 'Expected a promise to be resolved but it was ' + + 'rejected with ' + JSON.stringify(rej) + '.' + }; + } + ); +} + +export default assertPromiseIsResolved; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js new file mode 100644 index 0000000000000000000000000000000000000000..d5eb01e32491b281a1e1d650a307723253a61e39 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertPromiseIsResolvedWith.js @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import isPromiseLike from './isPromiseLike'; + +function assertPromiseIsResolvedWith(actualPromise, expectedValue) { + if (!isPromiseLike(actualPromise)) { + return Promise.reject().then(function () { + }, function () { + return {pass: false, message: 'Expected not be called on a promise.'}; + }); + } + + function tips(passed) { + return ( + 'Expected a promise ' + (passed ? 'not ' : '') + + 'to be resolved with ' + JSON.stringify(expectedValue[0])); + } + + const helper = {}; + return Promise.race([actualPromise, Promise.resolve(helper)]).then( + function (got) { + if (helper === got) { + return {pass: false, message: 'expect resolve, actualValue is isPending'}; + } + if (JSON.stringify(got) == JSON.stringify(expectedValue[0])) { + return { + pass: true, + message: 'actualValue was resolved with ' + JSON.stringify(got) + '.' + }; + } + return { + pass: false, + message: tips(false) + ' but it was resolved with ' + + JSON.stringify(got) + '.' + }; + }, + function (rej) { + return { + pass: false, + message: tips(false) + ' but it was rejected with ' + JSON.stringify(rej) + '.' + }; + } + ); +} + +export default assertPromiseIsResolvedWith; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js new file mode 100644 index 0000000000000000000000000000000000000000..749cab0daee3f156909f60c9375146c23d7aa322 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertThrowError.js @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertThrowError(actualValue, expected) { + let result = false; + let err; + if (typeof actualValue !== 'function') { + throw new Error('actualValue is not a function'); + } + try { + actualValue(); + return { + pass: result, + message: ' An error is not thrown while it is expected!' + }; + } catch (e) { + err = e; + } + + if (err instanceof Error) { + console.log(err.message); + if (err.message == expected[0]) { + result = true; + } + } + return { + pass: result, + message: 'expected throw failed , ' + err.message + ' is not ' + expected[0] + }; +} + +export default assertThrowError; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js new file mode 100644 index 0000000000000000000000000000000000000000..61f092d715dd1630297518b59ff13ef0940991e1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/assertUndefined.js @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function assertUndefined(actualValue) { + return { + pass: undefined === (actualValue), + message: 'expect Undefined, actualValue is ' + (actualValue) + }; +} + +export default assertUndefined; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js new file mode 100644 index 0000000000000000000000000000000000000000..b0be6674ee3474b08aff2f16b0a3c161aa8683df --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/DeepTypeUtils.js @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class DeepTypeUtils { + static getType_(value) { + return Object.prototype.toString.apply(value); + } + static isA_(typeName, value) { + return this.getType_(value) === '[object ' + typeName + ']'; + } + static isAsymmetricEqualityTester_(obj) { + return obj ? this.isA_('Function', obj.asymmetricMatch) : false; + } + + /** + * 是否是function + * @param value + */ + static isFunction_(value) { + return this.isA_('Function', value); + } + + /** + * 是否是undefined + * @param obj + */ + static isUndefined(obj) { + return obj === void 0; + } + + /** + * 是否是Node + * @param obj + */ + static isDomNode(obj) { + return obj !== null && + typeof obj === 'object' && + typeof obj.nodeType === 'number' && + typeof obj.nodeName === 'string'; + } + + /** + * 是否是promise对象 + * @param obj + */ + static isPromise (obj) { + return !!obj && obj.constructor === Promise; + }; + /** + * 是否是map对象 + * @param obj + */ + static isMap(obj) { + return ( + obj !== null && + typeof obj !== 'undefined' && + obj.constructor === Map + ); + } + + /** + * 是否是set对象 + * @param obj 对象 + */ + static isSet(obj) { + return ( + obj !== null && + typeof obj !== 'undefined' && + obj.constructor === Set + ); + } + + /** + * 对象是否有key属性 + * @param obj 对象 + * @param key 对象属性名称 + */ + static has(obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); + } + + /** + * 获取对象的自有属性 + * @param obj 对象 + * @param isArray 是否是数组,[object Array] + */ + static keys(obj, isArray) { + const extraKeys = []; + // 获取对象所有属性 + const allKeys = this.getAllKeys(obj); + if (!isArray) { + return allKeys; + } + if (allKeys.length === 0) { + return allKeys; + } + for (const k of allKeys) { + if (typeof k === 'symbol' || !/^[0-9]+$/.test(k)) { + extraKeys.push(k); + } + } + return extraKeys; + } + + /** + * 获取obj对象的所有属性 + * @param obj obj对象 + */ + static getAllKeys(obj) { + const keys = []; + for (let key in obj) { + if(this.has(obj, key)) { + keys.push(key); + } + } + const symbols = Object.getOwnPropertySymbols(obj); + for (const sym of symbols) { + if (obj.propertyIsEnumerable(sym)) { + keys.push(sym); + } + } + return keys; + } + +} +export default DeepTypeUtils; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js new file mode 100644 index 0000000000000000000000000000000000000000..4d991b4878fae2768bc7af074e275706d79e6f4d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/deepEquals/assertDeepEquals.js @@ -0,0 +1,311 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import DeepTypeUtils from './DeepTypeUtils' +function assertDeepEquals(actualValue, expected) { + console.log('actualValue:' + actualValue + ',expected:' + expected[0]); + let result = eq(actualValue, expected[0],[], []) + let msg = logMsg(actualValue, expected[0]); + return { + pass: result, + message: msg + }; +} + +/** + * 获取失败显示日志 + * @param actualValue 实际对象 + * @param expected 期待比较对象 + */ +function logMsg(actualValue, expected) { + // 获取a的对象名称 + const aClassName = Object.prototype.toString.call(actualValue); + const bClassName = Object.prototype.toString.call(expected); + let actualMsg; + let expectMsg; + if(aClassName == "[object Function]") { + actualMsg = "actualValue Function" + }else if(aClassName == "[object Promise]") { + actualMsg = "actualValue Promise" + }else if(aClassName == "[object Set]" || aClassName == "[object Map]") { + actualMsg = JSON.stringify(Array.from(actualValue));; + }else if(aClassName == "[object RegExp]") { + actualMsg = JSON.stringify(actualValue.source.replace("\\",""));; + } + else{ + actualMsg = JSON.stringify(actualValue); + } + if(bClassName == "[object Function]") { + expectMsg = "expected Function" + }else if(bClassName == "[object Promise]") { + expectMsg = "expected Promise" + }else if(aClassName == "[object Set]" || bClassName == "[object Map]") { + expectMsg = JSON.stringify(Array.from(expected)); + }else if(aClassName == "[object RegExp]") { + expectMsg = JSON.stringify(expected.source.replace("\\",""));; + } + else{ + expectMsg = JSON.stringify(expected); + } + return actualMsg + " is not deep equal " + expectMsg; +} + +function eq(a, b, aStack, bStack) { + let result = true; + console.log('a is:' + a + ',b is:' + b); + const asymmetricResult = asymmetricMatch_(a,b); + if (!DeepTypeUtils.isUndefined(asymmetricResult)) { + return asymmetricResult; + } + + if (a instanceof Error && b instanceof Error) { + result = a.message == b.message; + return result; + } + + if (a === b) { + result = a !== 0 || 1 / a == 1 / b; + return result; + } + + if (a === null || b === null) { + result = a === b; + return result; + } + // 获取a的对象名称 + const aClassName = Object.prototype.toString.call(a); + const bClassName = Object.prototype.toString.call(b); + console.log('aClassName is:' + aClassName); + console.log('bClassName is:' + bClassName); + // 不同类型不同对象 + if (aClassName != bClassName) { + return false; + } + // 俩个string对象 + if(aClassName === '[object String]') { + result = a == String(b); + return result; + } + // 俩个Number对象 + if(aClassName === '[object Number]') { + result = a != +a ? b != +b : a === 0 && b === 0 ? 1 / a == 1 / b : a == +b; + return result; + } + + if(aClassName === '[object Date]' || aClassName === '[object Boolean]') { + result = +a == +b; + return result; + } + + // 数组 + if(aClassName === '[object ArrayBuffer]') { + return eq(new Uint8Array(a), new Uint8Array(b), aStack, bStack); + } + + // 正则表达式 + if(aClassName === '[object RegExp]') { + return ( + a.source == b.source && + a.global == b.global && + a.multiline == b.multiline && + a.ignoreCase == b.ignoreCase + ); + } + + if (typeof a != 'object' || typeof b != 'object') { + return false; + } + + const aIsDomNode = DeepTypeUtils.isDomNode(a); + const bIsDomNode = DeepTypeUtils.isDomNode(b); + if (aIsDomNode && bIsDomNode) { + // At first try to use DOM3 method isEqualNode + result = a.isEqualNode(b); + return result; + } + if (aIsDomNode || bIsDomNode) { + return false; + } + const aIsPromise = DeepTypeUtils.isPromise(a); + const bIsPromise = DeepTypeUtils.isPromise(b); + if (aIsPromise && bIsPromise) { + return a === b; + } + let length = aStack.length; + while (length--) { + if (aStack[length] == a) { + return bStack[length] == b; + } + } + aStack.push(a); + bStack.push(b); + let size = 0; + + // 都是数组 + if(aClassName == '[object Array]') { + const aLength = a.length; + const bLength = b.length; + if (aLength !== bLength) { + // 数组长度不同,不是同一个对象 + return false; + } + for (let i = 0; i < aLength || i < bLength; i++) { + // 递归每一个元素是否相同 + result = eq(i < aLength ? a[i] : void 0, i < bLength ? b[i] : void 0, aStack, bStack) && result; + } + if (!result) { + return false; + } + } else if(DeepTypeUtils.isMap(a) && DeepTypeUtils.isMap(b)) { + if (a.size != b.size) { + return false; + } + const keysA = []; + const keysB = []; + a.forEach(function(valueA, keyA) { + keysA.push(keyA); + }); + b.forEach(function(valueB, keyB) { + keysB.push(keyB); + }); + const mapKeys = [keysA, keysB]; + const cmpKeys = [keysB, keysA]; + for (let i = 0; result && i < mapKeys.length; i++) { + const mapIter = mapKeys[i]; + const cmpIter = cmpKeys[i]; + + for (let j = 0; result && j < mapIter.length; j++) { + const mapKey = mapIter[j]; + const cmpKey = cmpIter[j]; + const mapValueA = a.get(mapKey); + let mapValueB; + if ( + DeepTypeUtils.isAsymmetricEqualityTester_(mapKey) || + (DeepTypeUtils.isAsymmetricEqualityTester_(cmpKey) && + eq(mapKey, cmpKey)) + ) { + mapValueB = b.get(cmpKey); + } else { + mapValueB = b.get(mapKey); + } + result = eq(mapValueA, mapValueB, aStack, bStack); + } + } + if (!result) { + return false; + } + } else if(DeepTypeUtils.isSet(a) && DeepTypeUtils.isSet(b)) { + if (a.size != b.size) { + return false; + } + const valuesA = []; + a.forEach(function(valueA) { + valuesA.push(valueA); + }); + const valuesB = []; + b.forEach(function(valueB) { + valuesB.push(valueB); + }); + const setPairs = [[valuesA, valuesB], [valuesB, valuesA]]; + const stackPairs = [[aStack, bStack], [bStack, aStack]]; + for (let i = 0; result && i < setPairs.length; i++) { + const baseValues = setPairs[i][0]; + const otherValues = setPairs[i][1]; + const baseStack = stackPairs[i][0]; + const otherStack = stackPairs[i][1]; + for (const baseValue of baseValues) { + let found = false; + for (let j = 0; !found && j < otherValues.length; j++) { + const otherValue = otherValues[j]; + const prevStackSize = baseStack.length; + // 深度比较对象 + found = eq(baseValue, otherValue, baseStack, otherStack); + if (!found && prevStackSize !== baseStack.length) { + baseStack.splice(prevStackSize); + otherStack.splice(prevStackSize); + } + } + result = result && found; + } + } + if (!result) { + return false; + } + } else { + const aCtor = a.constructor, + bCtor = b.constructor; + if ( + aCtor !== bCtor && + DeepTypeUtils.isFunction_(aCtor) && + DeepTypeUtils.isFunction_(bCtor) && + a instanceof aCtor && + b instanceof bCtor && + !(aCtor instanceof aCtor && bCtor instanceof bCtor) + ) { + return false; + } + } + + // 获取对象所有的属性集合 + const aKeys = DeepTypeUtils.keys(a, aClassName == '[object Array]'); + size = aKeys.length; + + // 俩个对象属性长度不一致, 俩对象不相同 + if (DeepTypeUtils.keys(b, bClassName == '[object Array]').length !== size) { + return false; + } + + // 俩对象属性数量相同, 递归比较每个属性值得值 + for (const key of aKeys) { + console.log('key is:' + key); + // b 没有 key 属性 + if(!DeepTypeUtils.has(b, key)) { + result = false; + continue; + } + if (!eq(a[key], b[key], aStack, bStack)) { + result = false; + } + } + if (!result) { + return false; + } + aStack.pop(); + bStack.pop(); + return result; +} + +function asymmetricMatch_(a, b) { + const asymmetricA = DeepTypeUtils.isAsymmetricEqualityTester_(a); + const asymmetricB = DeepTypeUtils.isAsymmetricEqualityTester_(b); + + if (asymmetricA === asymmetricB) { + return undefined; + } + +} + +/** + * 获取对象的自有属性 + * + * @param obj 对象 + * @param isArray 是否是一个数组 + */ +function keys(obj, isArray) { + const keys = []; + +} + +export default assertDeepEquals; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js new file mode 100644 index 0000000000000000000000000000000000000000..015ab19a2a0c4872d7cb490b61f8e1dd6a8ac90b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/assert/isPromiseLike.js @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function isPromiseLike(obj) { + return !!obj && isFunction_(obj.then); +} + +function isFunction_(value) { + return isA_('Function', value); +} + +function isA_(typeName, value) { + return getType_(value) === '[object ' + typeName + ']'; +} + +function getType_(value) { + return Object.prototype.toString.apply(value); +} + +export default isPromiseLike; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js new file mode 100644 index 0000000000000000000000000000000000000000..639dffc9cdb912f1f33a6ccb61868c9ed7c695bf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/DataDriver.js @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +const SUITES_KEY = 'suites'; +const SPECS_KEY = 'items'; +const DESCRIBE_KEY = 'describe'; +const IT_KEY = 'it'; +const PARAMS_KEY = 'params'; +const STRESS_KEY = 'stress'; + +class ObjectUtils { + static get(object, name, defaultValue) { + let result = defaultValue; + for (const key in object) { + if (key === name) { + return object[key]; + } + } + return result; + } + + static has(object, key) { + return Object.prototype.hasOwnProperty.call(object, key); + } +} + +class DataDriver { + constructor(attr) { + this.id = 'dataDriver'; + this.data = attr.data || {}; + } + + init(coreContext) { + this.coreContext = coreContext; + this.suiteService = this.coreContext.getDefaultService('suite'); + this.specService = this.coreContext.getDefaultService('spec'); + } + + getSpecParams() { + let specParams = []; + let suiteDesc = this.suiteService.getCurrentRunningSuite().description; + let specDesc = this.specService.getCurrentRunningSpec().description; + let suites = ObjectUtils.get(this.data, SUITES_KEY, []); + for (const suiteItem of suites) { + let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, ''); + if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) { + let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []); + for (const specItem of specs) { + if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) { + return ObjectUtils.get(specItem, PARAMS_KEY, specParams); + } + } + } + } + return specParams; + } + + getSuiteParams() { + let suiteParams = {}; + let suiteDesc = this.suiteService.getCurrentRunningSuite().description; + let suites = ObjectUtils.get(this.data, SUITES_KEY, []); + for (const suiteItem of suites) { + let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []); + if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) { + suiteParams = Object.assign({}, suiteParams, ObjectUtils.get(suiteItem, PARAMS_KEY, suiteParams)); + } + } + return suiteParams; + } + + getSpecStress(specDesc) { + let stress = 1; + let suiteDesc = this.suiteService.getCurrentRunningSuite().description; + let suites = ObjectUtils.get(this.data, SUITES_KEY, []); + for (const suiteItem of suites) { + let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, ''); + if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) { + let specs = ObjectUtils.get(suiteItem, SPECS_KEY, []); + for (const specItem of specs) { + if (ObjectUtils.has(specItem, IT_KEY) && ObjectUtils.get(specItem, IT_KEY) === specDesc) { + let tempStress = ObjectUtils.get(specItem, STRESS_KEY, stress); + return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress; + } + } + } + } + return stress; + } + + getSuiteStress(suiteDesc) { + let stress = 1; + let suites = ObjectUtils.get(this.data, SUITES_KEY, []); + for (const suiteItem of suites) { + let describeValue = ObjectUtils.get(suiteItem, DESCRIBE_KEY, []); + if (ObjectUtils.has(suiteItem, DESCRIBE_KEY) && (typeof describeValue === 'object') && describeValue.constructor === Array && describeValue.includes(suiteDesc)) { + let tempStress = ObjectUtils.get(suiteItem, STRESS_KEY, stress); + return (Number.isInteger(tempStress) && tempStress >= 1) ? tempStress : stress; + } + } + return stress; + } +} + +export default DataDriver; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/Filter.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/Filter.js new file mode 100644 index 0000000000000000000000000000000000000000..0ca3b4f412353ad0e9fa70bcfe775c905b5e02a9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/Filter.js @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class ClassFilter { + constructor(suiteName, itName, params) { + this.suiteName = suiteName; + this.itName = itName; + this.params = params; + } + + filterSuite() { + return !this.params.split(',').map(item => item.split('#')[0]).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false); + } + + filterIt() { + let classArray = this.params.split(',') || []; + let suiteFilterResult = classArray.filter(item => !item.includes('#')).map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false); + let itFilterResult = classArray.filter(item => item.includes('#')).map(item => item == (this.suiteName + '#' + this.itName)).reduce((pre, cur) => pre || cur, false); + return !(suiteFilterResult || itFilterResult); + } +} + +class NotClassFilter { + constructor(suiteName, itName, params) { + this.suiteName = suiteName; + this.itName = itName; + this.params = params; + } + + filterSuite() { + return this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false); + } + + filterIt() { + return this.params.split(',').some(item => item == (this.suiteName + '#' + this.itName)); + } +} + +class SuiteAndItNameFilter { + constructor(suiteName, itName, params) { + this.suiteName = suiteName; + this.itName = itName; + this.params = params; + } + + filterSuite() { + return !this.params.split(',').map(item => item == this.suiteName).reduce((pre, cur) => pre || cur, false); + } + + filterIt() { + return !this.params.split(',').map(item => item == this.itName).reduce((pre, cur) => pre || cur, false); + } +} + + +class TestTypesFilter { + constructor(suiteName, itName, fi, params) { + this.suiteName = suiteName; + this.itName = itName; + this.params = params; + this.fi = fi; + } + + filterIt() { + return !((this.params === (this.fi & this.params)) || this.fi === 0); + } +} + +export {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter}; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js new file mode 100644 index 0000000000000000000000000000000000000000..745f137e3d48ff86bbd910f6639affe56a773654 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/config/configService.js @@ -0,0 +1,292 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {ClassFilter, NotClassFilter, SuiteAndItNameFilter, TestTypesFilter} from './Filter'; +const STRESS_RULE = /^[1-9]\d*$/; + +class ConfigService { + constructor(attr) { + this.id = attr.id; + this.supportAsync = false; + this.random = false; + this.filterValid = []; + this.filter = 0; + this.flag = false; + this.suite = null; + this.itName = null; + this.testType = null; + this.level = null; + this.size = null; + this.class = null; + this.notClass = null; + this.timeout = null; + // 遇错即停模式配置 + this.breakOnError = false; + // 压力测试配置 + this.stress = null; + } + + init(coreContext) { + this.coreContext = coreContext; + } + + isNormalInteger(str) { + const n = Math.floor(Number(str)); + return n !== Infinity && String(n) === String(str) && n >= 0; + } + + getStress() { + if (this.stress === undefined || this.stress === '' || this.stress === null) { + return 1; + } + return !this.stress.match(STRESS_RULE) ? 1 : Number.parseInt(this.stress); + } + + basicParamValidCheck(params) { + let size = params.size; + if (size !== undefined && size !== '' && size !== null) { + let sizeArray = ['small', 'medium', 'large']; + if (sizeArray.indexOf(size) === -1) { + this.filterValid.push('size:' + size); + } + } + let level = params.level; + if (level !== undefined && level !== '' && level !== null) { + let levelArray = ['0', '1', '2', '3', '4']; + if (levelArray.indexOf(level) === -1) { + this.filterValid.push('level:' + level); + } + } + let testType = params.testType; + if (testType !== undefined && testType !== '' && testType !== null) { + let testTypeArray = ['function', 'performance', 'power', 'reliability', 'security', + 'global', 'compatibility', 'user', 'standard', 'safety', 'resilience']; + if (testTypeArray.indexOf(testType) === -1) { + this.filterValid.push('testType:' + testType); + } + } + } + + filterParamValidCheck(params) { + let timeout = params.timeout; + if (timeout !== undefined && timeout !== '' && timeout !== null) { + if (!this.isNormalInteger(timeout)) { + this.filterValid.push('timeout:' + timeout); + } + } + + let paramKeys = ['dryRun', 'random', 'breakOnError', 'coverage']; + for (const key of paramKeys) { + if (params[key] !== undefined && params[key] !== 'true' && params[key] !== 'false') { + this.filterValid.push(`${key}:${params[key]}`); + } + } + + // 压力测试参数验证,正整数 + if (params.stress !== undefined && params.stress !== '' && params.stress !== null) { + if (!params.stress.match(STRESS_RULE)) { + this.filterValid.push('stress:' + params.stress); + } + } + + let nameRule = /^[A-Za-z]{1}[\w#,.]*$/; + let paramClassKeys = ['class', 'notClass']; + for (const key of paramClassKeys) { + if (params[key] !== undefined && params[key] !== '' && params[key] !== null) { + let classArray = params[key].split(','); + classArray.forEach(item => !item.match(nameRule) ? this.filterValid.push(`${key}:${params[key]}`) : null); + } + } + } + + setConfig(params) { + this.basicParamValidCheck(params); + this.filterParamValidCheck(params); + try { + this.class = params.class; + this.notClass = params.notClass; + this.flag = params.flag || {flag: false}; + this.suite = params.suite; + this.itName = params.itName; + this.filter = params.filter; + this.testType = params.testType; + this.level = params.level; + this.size = params.size; + this.timeout = params.timeout; + this.dryRun = params.dryRun; + this.breakOnError = params.breakOnError; + this.random = params.random === 'true' ? true : false; + this.stress = params.stress; + this.coverage = params.coverage; + this.filterParam = { + testType: { + 'function': 1, + 'performance': 1 << 1, + 'power': 1 << 2, + 'reliability': 1 << 3, + 'security': 1 << 4, + 'global': 1 << 5, + 'compatibility': 1 << 6, + 'user': 1 << 7, + 'standard': 1 << 8, + 'safety': 1 << 9, + 'resilience': 1 << 10, + }, + level: { + '0': 1 << 24, + '1': 1 << 25, + '2': 1 << 26, + '3': 1 << 27, + '4': 1 << 28, + }, + size: { + 'small': 1 << 16, + 'medium': 1 << 17, + 'large': 1 << 18, + } + }; + this.parseParams(); + } catch (err) { + console.info('setConfig error: ' + err.message); + } + } + + parseParams() { + if (this.filter != null) { + return; + } + let testTypeFilter = 0; + let sizeFilter = 0; + let levelFilter = 0; + if (this.testType != null) { + testTypeFilter = this.testType.split(',') + .map(item => this.filterParam.testType[item] || 0) + .reduce((pre, cur) => pre | cur, 0); + } + if (this.level != null) { + levelFilter = this.level.split(',') + .map(item => this.filterParam.level[item] || 0) + .reduce((pre, cur) => pre | cur, 0); + } + if (this.size != null) { + sizeFilter = this.size.split(',') + .map(item => this.filterParam.size[item] || 0) + .reduce((pre, cur) => pre | cur, 0); + } + this.filter = testTypeFilter | sizeFilter | levelFilter; + console.info('filter params:' + this.filter); + } + + isCurrentSuite(description) { + if (this.suite !== undefined && this.suite !== '' && this.suite !== null) { + let suiteArray = this.suite.split(','); + return suiteArray.indexOf(description) !== -1; + } + return false; + } + + filterSuite(currentSuiteName) { + let filterArray = []; + if (this.suite !== undefined && this.suite !== '' && this.suite !== null) { + filterArray.push(new SuiteAndItNameFilter(currentSuiteName, '', this.suite)); + } + if (this.class !== undefined && this.class !== '' && this.class !== null) { + filterArray.push(new ClassFilter(currentSuiteName, '', this.class)); + } + if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) { + filterArray.push(new NotClassFilter(currentSuiteName, '', this.notClass)); + } + + let result = filterArray.map(item => item.filterSuite()).reduce((pre, cur) => pre || cur, false); + return result; + } + + filterDesc(currentSuiteName, desc, fi, coreContext) { + let filterArray = []; + if (this.itName !== undefined && this.itName !== '' && this.itName !== null) { + filterArray.push(new SuiteAndItNameFilter(currentSuiteName, desc, this.itName)); + } + if (this.class !== undefined && this.class !== '' && this.class !== null) { + filterArray.push(new ClassFilter(currentSuiteName, desc, this.class)); + } + if (this.notClass !== undefined && this.notClass !== '' && this.notClass !== null) { + filterArray.push(new NotClassFilter(currentSuiteName, desc, this.notClass)); + } + if (typeof (this.filter) !== 'undefined' && this.filter !== 0 && fi !== 0) { + filterArray.push(new TestTypesFilter('', '', fi, this.filter)); + } + let result = filterArray.map(item => item.filterIt()).reduce((pre, cur) => pre || cur, false); + return result; + } + + isRandom() { + return this.random || false; + } + + isBreakOnError() { + return this.breakOnError !== 'true' ? false : true; + } + + setSupportAsync(value) { + this.supportAsync = value; + } + + isSupportAsync() { + return this.supportAsync; + } + + translateParams(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s itName', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun', '-s random', '-s breakOnError', '-s stress', + '-s coverage', 'class', 'notClass', 'suite', 'itName', + 'level', 'testType', 'size', 'timeout', 'dryRun', 'random', + 'breakOnError', 'stress', 'coverage' + ]); + let targetParams = {}; + for (const key in parameters) { + if (keySet.has(key)) { + var newKey = key.replace("-s ", ""); + targetParams[newKey] = parameters[key]; + } + } + return targetParams; + } + translateParamsToString(parameters) { + const keySet = new Set([ + '-s class', '-s notClass', '-s suite', '-s itName', + '-s level', '-s testType', '-s size', '-s timeout', + '-s dryRun', '-s random', '-s breakOnError', '-s stress', + '-s coverage','class', 'notClass', 'suite', 'itName', + 'level', 'testType', 'size', 'timeout', 'dryRun', 'random', + 'breakOnError', 'stress', 'coverage' + ]); + let targetParams = ''; + for (const key in parameters) { + if (keySet.has(key)) { + targetParams += ' ' + key + ' ' + parameters[key]; + } + } + return targetParams.trim(); + } + + execute() { + } +} + +export { + ConfigService +}; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js new file mode 100644 index 0000000000000000000000000000000000000000..4707dea3eba464fd7446bf215481f4049b0cfe00 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/coverage/coverageCollect.js @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SysTestKit from "../kit/SysTestKit"; + +export async function collectCoverageData() { + if (globalThis.__coverage__ === undefined) { + return; + } + const strJson = JSON.stringify(globalThis.__coverage__); + const strLen = strJson.length; + const maxLen = 500; + const maxCount = Math.floor(strLen / maxLen); + const OHOS_REPORT_COVERAGE_DATA = 'OHOS_REPORT_COVERAGE_DATA:'; + for (let count = 0; count <= maxCount; count++) { + await SysTestKit.print(`${OHOS_REPORT_COVERAGE_DATA} ${strJson.substring(count * maxLen, (count + 1) * maxLen)}`); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js new file mode 100644 index 0000000000000000000000000000000000000000..d73d46d912dc2f86a645327548b5d58a17c168bf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/kit/SysTestKit.js @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class SysTestKit { + + static delegator = null; + static systemTime = null; + + constructor() { + this.id = 'sysTestKit'; + this.index = 0; + } + + static actionStart(tag) { + console.info(JSON.stringify(tag)); + var message = '\n' + 'OHOS_REPORT_ACTIONSTART: ' + JSON.stringify(tag) + '\n'; + SysTestKit.print(message); + console.info(tag + ' actionStart print success'); + } + + static actionEnd(tag) { + console.info(JSON.stringify(tag)); + var message = '\n' + 'OHOS_REPORT_ACTIONEND: ' + JSON.stringify(tag) + '\n'; + SysTestKit.print(message); + console.info(tag + ' actionEnd print success'); + } + + static async existKeyword(keyword, timeout) { + let reg = new RegExp(/^[a-zA-Z0-9]{1,}$/) + if (!reg.test(keyword)) { + throw new Error('keyword must contain more than one string, and only letters and numbers are supported.') + } + timeout = timeout || 4; + + let searchResult = false; + let cmd = 'hilog -x | grep -i \'' + keyword + '\' | wc -l'; + await executePromise(cmd, timeout).then((data) => { + searchResult = data; + }); + return searchResult; + } + static async print(message) { + if ('printSync' in SysTestKit.delegator) { + console.debug(`printSync called ...`); + SysTestKit.delegator.printSync(message); + } else { + await SysTestKit.delegator.print(message); + } + } + + static async getRealTime() { + let currentTime = new Date().getTime(); + if (SysTestKit.systemTime !== null && SysTestKit.systemTime !== undefined) { + await SysTestKit.systemTime.getRealTime().then((time) => { + console.info(`systemTime.getRealTime success data: ${JSON.stringify(time)}`); + currentTime = time; + }).catch((error) => { + console.error(`failed to systemTime.getRealTime because ${JSON.stringify(error)}`); + }); + } + return currentTime; + } +} + +function executePromise(cmd, timeout) { + return new Promise((resolve, reject) => { + SysTestKit.delegator.executeShellCommand(cmd, timeout, + (error, data) => { + console.info('existKeyword CallBack: err : ' + JSON.stringify(error)); + console.info('existKeyword CallBack: data : ' + JSON.stringify(data)); + resolve(parseInt(data.stdResult) > 3 ? true : false); + }); + }); +} + +export default SysTestKit; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js new file mode 100644 index 0000000000000000000000000000000000000000..6a9d7aac464e95383ea31385284b6603c34e084c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ArgumentMatchers.js @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class ArgumentMatchers { + ANY = ""; + ANY_STRING = ""; + ANY_BOOLEAN = ""; + ANY_NUMBER = ""; + ANY_OBJECT = ""; + ANY_FUNCTION = ""; + MATCH_REGEXS = ""; + + static any() { + } + + static anyString() { + } + + static anyBoolean() { + } + + static anyNumber() { + } + + static anyObj() { + } + + static anyFunction() { + } + + static matchRegexs() { + let regex = arguments[0]; + if (ArgumentMatchers.isRegExp(regex)) { + return regex; + } + throw Error("not a regex"); + } + + static isRegExp(value) { + return Object.prototype.toString.call(value) === "[object RegExp]"; + } + + matcheReturnKey() { + let arg = arguments[0]; + let regex = arguments[1]; + let stubSetKey = arguments[2]; + + if (stubSetKey && stubSetKey == this.ANY) { + return this.ANY; + } + + if (typeof arg === "string" && !regex) { + return this.ANY_STRING; + } + + if (typeof arg === "boolean" && !regex) { + return this.ANY_BOOLEAN; + } + + if (typeof arg === "number" && !regex) { + return this.ANY_NUMBER; + } + + if (typeof arg === "object" && !regex) { + return this.ANY_OBJECT; + } + + if (typeof arg === "function" && !regex) { + return this.ANY_FUNCTION; + } + + if (typeof arg === "string" && regex) { + return regex.test(arg); + } + + return null; + } + + matcheStubKey() { + let key = arguments[0]; + + if (key === ArgumentMatchers.any) { + return this.ANY; + } + + if (key === ArgumentMatchers.anyString) { + return this.ANY_STRING; + } + if (key === ArgumentMatchers.anyBoolean) { + return this.ANY_BOOLEAN; + } + if (key === ArgumentMatchers.anyNumber) { + return this.ANY_NUMBER; + } + if (key === ArgumentMatchers.anyObj) { + return this.ANY_OBJECT; + } + if (key === ArgumentMatchers.anyFunction) { + return this.ANY_FUNCTION; + } + + if (ArgumentMatchers.isRegExp(key)) { + return key; + } + + return null; + } +} + +export default ArgumentMatchers; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js new file mode 100644 index 0000000000000000000000000000000000000000..c6a866a6df662ad10a7f6869dcbc2381fa47bcdc --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/ExtendInterface.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class ExtendInterface { + constructor(mocker) { + this.mocker = mocker; + } + + stub() { + this.params = arguments; + return this; + } + + stubMockedCall(returnInfo) { + this.mocker.stubApply(this, this.params, returnInfo); + } + + afterReturn(value) { + this.stubMockedCall(function () { + return value; + }); + } + + afterReturnNothing() { + this.stubMockedCall(function () { + return undefined; + }); + } + + afterAction(action) { + this.stubMockedCall(action); + } + + afterThrow(msg) { + this.stubMockedCall(function () { + throw msg; + }); + } + + clear() { + this.mocker.clear(); + } +} + +export default ExtendInterface; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js new file mode 100644 index 0000000000000000000000000000000000000000..a23462472c023f0ef81a6a6d274f14f8649a8dc0 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/MockKit.js @@ -0,0 +1,256 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import ExtendInterface from "./ExtendInterface"; +import VerificationMode from "./VerificationMode"; +import ArgumentMatchers from "./ArgumentMatchers"; + +class MockKit { + + constructor() { + this.mFunctions = []; + this.stubs = new Map(); + this.recordCalls = new Map(); + this.currentSetKey = null; + this.mockObj = null; + this.recordMockedMethod = new Map(); + } + + init() { + this.reset(); + } + + reset() { + this.mFunctions = []; + this.stubs = {}; + this.recordCalls = {}; + this.currentSetKey = null; + this.mockObj = null; + this.recordMockedMethod = new Map(); + } + + clearAll() { + this.reset(); + var props = Object.keys(this); + for (var i = 0; i < props.length; i++) { + delete this[props[i]]; + } + + var props = Object.getOwnPropertyNames(this); + for (var i = 0; i < props.length; i++) { + delete this[props[i]]; + } + for (var key in this) { + delete this[key]; + } + } + + clear(obj) { + if (!obj) throw Error("Please enter an object to be cleaned"); + if (typeof (obj) != 'object') throw new Error('Not a object'); + this.recordMockedMethod.forEach(function (value, key, map) { + if (key) { + obj[key] = value; + } + }); + } + + ignoreMock(obj, method) { + if (typeof (obj) != 'object') throw new Error('Not a object'); + if (typeof (method) != 'function') throw new Error('Not a function'); + let og = this.recordMockedMethod.get(method.propName); + if (og) { + obj[method.propName] = og; + this.recordMockedMethod.set(method.propName, undefined); + } + } + + extend(dest, source) { + dest["stub"] = source["stub"]; + dest["afterReturn"] = source["afterReturn"]; + dest["afterReturnNothing"] = source["afterReturnNothing"]; + dest["afterAction"] = source["afterAction"]; + dest["afterThrow"] = source["afterThrow"]; + dest["stubMockedCall"] = source["stubMockedCall"]; + dest["clear"] = source["clear"]; + return dest; + } + + stubApply(f, params, returnInfo) { + let values = this.stubs.get(f); + if (!values) { + values = new Map(); + } + let key = params[0]; + if (typeof key == "undefined") { + key = "anonymous-mock-" + f.propName; + } + let matcher = new ArgumentMatchers(); + if (matcher.matcheStubKey(key)) { + key = matcher.matcheStubKey(key); + if (key) { + this.currentSetKey = key; + } + } + values.set(key, returnInfo); + this.stubs.set(f, values); + } + + getReturnInfo(f, params) { + let values = this.stubs.get(f); + if (!values) { + return undefined; + } + let retrunKet = params[0]; + if (typeof retrunKet == "undefined") { + retrunKet = "anonymous-mock-" + f.propName; + } + let stubSetKey = this.currentSetKey; + + if (this.currentSetKey && (typeof (retrunKet) != "undefined")) { + retrunKet = stubSetKey; + } + let matcher = new ArgumentMatchers(); + if (matcher.matcheReturnKey(params[0], undefined, stubSetKey) && matcher.matcheReturnKey(params[0], undefined, stubSetKey) != stubSetKey) { + retrunKet = params[0]; + } + + values.forEach(function (value, key, map) { + if (ArgumentMatchers.isRegExp(key) && matcher.matcheReturnKey(params[0], key)) { + retrunKet = key; + } + }); + + return values.get(retrunKet); + } + + findName(obj, value) { + let properties = this.findProperties(obj); + let name = null; + properties.forEach( + function (va1, idx, array) { + if (obj[va1] === value) { + name = va1; + } + } + ); + return name; + } + + isFunctionFromPrototype(f, container, propName) { + if (container.constructor != Object && container.constructor.prototype !== container) { + return container.constructor.prototype[propName] === f; + } + return false; + } + + findProperties(obj, ...arg) { + function getProperty(new_obj) { + if (new_obj.__proto__ === null) { + return []; + } + let properties = Object.getOwnPropertyNames(new_obj); + return [...properties, ...getProperty(new_obj.__proto__)]; + } + return getProperty(obj); + } + + recordMethodCall(originalMethod, args) { + Function.prototype.getName = function () { + return this.name || this.toString().match(/function\s*([^(]*)\(/)[1]; + }; + let name = originalMethod.getName(); + let arglistString = name + '(' + Array.from(args).toString() + ')'; + let records = this.recordCalls.get(arglistString); + if (!records) { + records = 0; + } + records++; + this.recordCalls.set(arglistString, records); + } + + mockFunc(originalObject, originalMethod) { + let tmp = this; + this.originalMethod = originalMethod; + let f = function () { + let args = arguments; + let action = tmp.getReturnInfo(f, args); + if (originalMethod) { + tmp.recordMethodCall(originalMethod, args); + } + if (action) { + return action.apply(this, args); + } + }; + + f.container = null || originalObject; + f.original = originalMethod || null; + + if (originalObject && originalMethod) { + if (typeof (originalMethod) != 'function') throw new Error('Not a function'); + var name = this.findName(originalObject, originalMethod); + originalObject[name] = f; + this.recordMockedMethod.set(name, originalMethod); + f.propName = name; + f.originalFromPrototype = this.isFunctionFromPrototype(f.original, originalObject, f.propName); + } + f.mocker = this; + this.mFunctions.push(f); + this.extend(f, new ExtendInterface(this)); + return f; + } + + verify(methodName, argsArray) { + if (!methodName) { + throw Error("not a function name"); + } + let a = this.recordCalls.get(methodName + '(' + argsArray.toString() + ')'); + return new VerificationMode(a ? a : 0); + } + + mockObject(object) { + if (!object || typeof object === "string") { + throw Error(`this ${object} cannot be mocked`); + } + const _this = this; + let mockedObject = {}; + let keys = Reflect.ownKeys(object); + keys.filter(key => (typeof Reflect.get(object, key)) === 'function') + .forEach(key => { + mockedObject[key] = object[key]; + mockedObject[key] = _this.mockFunc(mockedObject, mockedObject[key]); + }); + return mockedObject; + } +} + +function ifMockedFunction(f) { + if (Object.prototype.toString.call(f) != "[object Function]" && + Object.prototype.toString.call(f) != "[object AsyncFunction]") { + throw Error("not a function"); + } + if (!f.stub) { + throw Error("not a mock function"); + } + return true; +} + +function when(f) { + if (ifMockedFunction(f)) { + return f.stub.bind(f); + } +} + +export {MockKit, when}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js new file mode 100644 index 0000000000000000000000000000000000000000..7bd04c8473985ec57f5b14fc3ae84e9cf7b31f39 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/mock/VerificationMode.js @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import {expect} from '../../interface'; + +class VerificationMode { + constructor(times) { + this.doTimes = times; + } + + times(count) { + expect(count).assertEqual(this.doTimes); + } + + never() { + console.log(this.doTimes); + expect(0).assertEqual(this.doTimes); + } + + once() { + expect(1).assertEqual(this.doTimes); + } + + atLeast(count) { + if (count > this.doTimes) { + throw Error('failed ' + count + ' greater than the actual execution times of method'); + } + } + + atMost(count) { + if (count < this.doTimes) { + throw Error('failed ' + count + ' less than the actual execution times of method'); + } + } +} + +export default VerificationMode; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js new file mode 100644 index 0000000000000000000000000000000000000000..da120dd09c0e74e46b9138b7598661e380010210 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/OhReport.js @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SysTestKit from "../kit/SysTestKit"; +import {collectCoverageData} from '../coverage/coverageCollect'; + +class OhReport { + constructor(attr) { + this.delegator = attr.delegator; + this.abilityDelegatorArguments = attr.abilityDelegatorArguments; + this.id = 'report'; + this.index = 0; + this.duration = 0; + } + + init(coreContext) { + this.coreContext = coreContext; + this.suiteService = this.coreContext.getDefaultService('suite'); + this.specService = this.coreContext.getDefaultService('spec'); + } + + taskStart() { + } + + async taskDone() { + if (this.abilityDelegatorArguments !== null) { + this.taskDoneTime = new Date().getTime(); + let summary = this.suiteService.getSummary(); + const configService = this.coreContext.getDefaultService('config'); + if (configService['coverage'] === 'true') { + await collectCoverageData(); + } + let message = '\n' + 'OHOS_REPORT_RESULT: stream=Tests run: ' + summary.total + ', Failure: ' + summary.failure; + message += ', Error: ' + summary.error; + message += ', Pass: ' + summary.pass; + message += ', Ignore: ' + summary.ignore; + message += '\n' + 'OHOS_REPORT_CODE: ' + (summary.failure > 0 ? -1 : 0) + '\n'; + let isHasError = summary.failure > 0 || summary.error > 0; + let config = this.coreContext.getDefaultService('config'); + if (config.isBreakOnError() && isHasError) { + // 未执行全部说明 + message += '\n' + 'OHOS_REPORT_RESULT: breakOnError model, Stopping whole test suite if one specific test case failed or error' + '\n'; + } + message += 'OHOS_REPORT_STATUS: taskconsuming=' + summary.duration + '\n'; + console.info(message); + await SysTestKit.print(message); + } + console.info('report print success'); + this.delegator.finishTest('your test finished!!!', 0, () => { }); + } + + incorrectFormat() { + if (this.coreContext.getDefaultService('config').filterValid.length !== 0) { + var value = this.coreContext.getDefaultService('config').filterValid; + var message = 'this param ' + value.join(',') + ' is invalid' + '\n'; + this.delegator.finishTest(message, 0, () => { + }); + } + } + + async suiteStart() { + if (this.abilityDelegatorArguments !== null) { + let message = '\n' + 'OHOS_REPORT_SUM: ' + this.suiteService.getCurrentRunningSuite().getSpecsNum(); + message += '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description + '\n'; + console.info(message); + await SysTestKit.print(message); + console.info(this.suiteService.getCurrentRunningSuite().description + ' suiteStart print success'); + } + } + + async suiteDone() { + if (this.abilityDelegatorArguments !== null) { + let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description; + message += '\n' + 'OHOS_REPORT_STATUS: suiteconsuming=' + this.suiteService.getCurrentRunningSuite().duration + '\n'; + console.info(message); + await SysTestKit.print(message); + console.info(this.suiteService.getCurrentRunningSuite().description + ' suiteDone print success'); + } + } + + async specStart() { + if (this.abilityDelegatorArguments !== null) { + let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description; + message += '\n' + 'OHOS_REPORT_STATUS: current=' + (++this.index); + message += '\n' + 'OHOS_REPORT_STATUS: id=JS'; + message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal(); + message += '\n' + 'OHOS_REPORT_STATUS: stream='; + message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description; + message += '\n' + 'OHOS_REPORT_STATUS_CODE: 1' + '\n'; + console.info(message); + await SysTestKit.print(message); + console.info(this.specService.currentRunningSpec.description + ' specStart start print success'); + } + } + + async specDone() { + if (this.abilityDelegatorArguments !== null) { + let message = '\n' + 'OHOS_REPORT_STATUS: class=' + this.suiteService.getCurrentRunningSuite().description; + message += '\n' + 'OHOS_REPORT_STATUS: current=' + (this.index); + message += '\n' + 'OHOS_REPORT_STATUS: id=JS'; + message += '\n' + 'OHOS_REPORT_STATUS: numtests=' + this.specService.getTestTotal(); + let errorMsg = ''; + if (this.specService.currentRunningSpec.error) { + message += '\n' + 'OHOS_REPORT_STATUS: stack=' + this.specService.currentRunningSpec.error.message; + message += '\n' + 'OHOS_REPORT_STATUS: stream='; + message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description; + message += '\n' + this.specService.currentRunningSpec.error.message; + message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description; + message += '\n' + 'OHOS_REPORT_STATUS_CODE: -1' + '\n'; + } else if (this.specService.currentRunningSpec.result) { + if (this.specService.currentRunningSpec.result.failExpects.length > 0) { + this.specService.currentRunningSpec.result.failExpects.forEach(failExpect => { + errorMsg = failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue)); + }); + message += '\n' + 'OHOS_REPORT_STATUS: stack=' + errorMsg; + message += '\n' + 'OHOS_REPORT_STATUS: stream='; + message += '\n' + 'Error in ' + this.specService.currentRunningSpec.description; + message += '\n' + errorMsg + '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description; + message += '\n' + 'OHOS_REPORT_STATUS_CODE: -2' + '\n'; + } else { + message += '\n' + 'OHOS_REPORT_STATUS: stream='; + message += '\n' + 'OHOS_REPORT_STATUS: test=' + this.specService.currentRunningSpec.description; + message += '\n' + 'OHOS_REPORT_STATUS_CODE: 0' + '\n'; + } + } else { + message += '\n'; + } + message += 'OHOS_REPORT_STATUS: consuming=' + this.specService.currentRunningSpec.duration + '\n'; + console.info(message); + await SysTestKit.print(message); + console.info(this.specService.currentRunningSpec.description + ' specDone end print success'); + } + } +} + +export default OhReport; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js new file mode 100644 index 0000000000000000000000000000000000000000..852fbcd5cbf97e776ebe5177a029df0f516594a5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/module/report/ReportExtend.js @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +class ReportExtend { + constructor(fileModule) { + this.id = 'extend'; + this.fileModule = fileModule; + } + + init(coreContext) { + this.coreContext = coreContext; + this.suiteService = this.coreContext.getDefaultService('suite'); + } + + taskStart() { + + } + + taskDone() { + const report = { + tag: 'testsuites', + name: 'summary_report', + timestamp: new Date().toDateString(), + time: '1', + errors: 0, + failures: 0, + tests: 0, + children: [] + }; + const rootSuite = this.suiteService.rootSuite; + if (rootSuite && rootSuite.childSuites) { + for (let testsuite of rootSuite.childSuites) { + let suiteReport = { + tag: 'testsuite', + name: testsuite['description'], + errors: 0, + tests: 0, + failures: 0, + time: '0.1', + children: [] + }; + let specs = testsuite['specs']; + for (let testcase of specs) { + report.tests++; + suiteReport.tests++; + let caseReport = { + tag: 'testcase', + name: testcase['description'], + status: 'run', + time: '0.0', + classname: testsuite['description'] + }; + if (testcase.error) { + caseReport['result'] = false; + caseReport['children'] = [{ + tag: 'error', + type: '', + message: testcase.error.message + }]; + report.errors++; + suiteReport.errors++; + } else if (testcase.result.failExpects.length > 0) { + caseReport['result'] = false; + let message = ''; + testcase.result.failExpects.forEach(failExpect => { + message += failExpect.message || ('expect ' + failExpect.actualValue + ' ' + failExpect.checkFunc + ' ' + (failExpect.expectValue || '')) + ';'; + }); + caseReport['children'] = [{ + tag: 'failure', + type: '', + message: message + }]; + report.failures++; + suiteReport.failures++; + } else { + caseReport['result'] = true; + } + suiteReport.children.push(caseReport); + } + report.children.push(suiteReport); + } + } + + let reportXml = '\n' + json2xml(report); + this.fileModule.writeText({ + uri: 'internal://app/report.xml', + text: reportXml, + success: function () { + console.info('call success callback success'); + }, + fail: function (data, code) { + console.info('call fail callback success:'); + }, + complete: function () { + console.info('call complete callback success'); + } + }); + } +} + +function json2xml(json) { + let tagName; + let hasChildren = false; + let childrenStr = ''; + let attrStr = ''; + for (let key in json) { + if (key === 'tag') { + tagName = json[key]; + } else if (key === 'children') { + if (json[key].length > 0) { + hasChildren = true; + for (let child of json[key]) { + childrenStr += json2xml(child); + } + } + } else { + attrStr += ` ${key}="${json[key]}"`; + } + } + let xml = `<${tagName}${attrStr}`; + xml += hasChildren ? `>${childrenStr}` : '/>'; + return xml; +} + +export default ReportExtend; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js new file mode 100644 index 0000000000000000000000000000000000000000..e55a2e4a2db3fdef4b983fa9cb63bf5c58b76fb4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/oh_modules/.ohpm/@ohos+hypium@1.0.6/oh_modules/@ohos/hypium/src/main/service.js @@ -0,0 +1,929 @@ +/* + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import SysTestKit from "./module/kit/SysTestKit"; + +class AssertException extends Error { + constructor(message) { + super(); + this.name = "AssertException"; + this.message = message; + } +} + +function getFuncWithArgsZero(func, timeout, isStressTest) { + return new Promise(async (resolve, reject) => { + let timer = null; + if (!isStressTest) { + timer = setTimeout(() => { + reject(new Error('execute timeout ' + timeout + 'ms')); + }, timeout); + } + try { + await func(); + } catch (err) { + reject(err); + } + timer !== null ? clearTimeout(timer) : null; + resolve(); + }); +} + +function getFuncWithArgsOne(func, timeout, isStressTest) { + return new Promise(async (resolve, reject) => { + let timer = null; + if (!isStressTest) { + timer = setTimeout(() => { + reject(new Error('execute timeout ' + timeout + 'ms')); + }, timeout);; + } + + function done() { + timer !== null ? clearTimeout(timer) : null; + resolve(); + } + + try { + await func(done); + } catch (err) { + timer !== null ? clearTimeout(timer) : null; + reject(err); + } + }); +} + +function getFuncWithArgsTwo(func, timeout, paramItem, isStressTest) { + return new Promise(async (resolve, reject) => { + let timer = null; + if (!isStressTest) { + timer = setTimeout(() => { + reject(new Error('execute timeout ' + timeout + 'ms')); + }, timeout); + } + + function done() { + timer !== null ? clearTimeout(timer) : null; + resolve(); + } + + try { + await func(done, paramItem); + } catch (err) { + timer !== null ? clearTimeout(timer) : null; + reject(err); + } + }); +} + +function processFunc(coreContext, func) { + let argNames = ((func || '').toString() + .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '') + .match(/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m) || ['', '', ''])[2] + .split(',') // split parameters + .map(item => item.replace(/^\s*(_?)(.+?)\1\s*$/, name => name.split('=')[0].trim())) + .filter(String); + let funcLen = func.length; + let processedFunc; + const config = coreContext.getDefaultService('config'); + config.setSupportAsync(true); + const timeout = + (config.timeout === undefined ? 5000 : config.timeout); + const isStressTest = (coreContext.getServices('dataDriver') !== undefined || config.getStress() > 1); + switch (funcLen) { + case 0: { + processedFunc = function () { + return getFuncWithArgsZero(func, timeout, isStressTest); + }; + break; + } + case 1: { + if (argNames[0] === 'data') { + processedFunc = function (paramItem) { + func(paramItem); + }; + } else { + processedFunc = function () { + return getFuncWithArgsOne(func, timeout, isStressTest); + }; + } + break; + } + default: { + processedFunc = function (paramItem) { + return getFuncWithArgsTwo(func, timeout, paramItem, isStressTest); + }; + break; + } + } + return processedFunc; +} + +function secureRandomNumber() { + return crypto.randomBytes(8).readUInt32LE() / 0xffffffff; +} + +class SuiteService { + constructor(attr) { + this.id = attr.id; + this.rootSuite = new SuiteService.Suite({}); + this.currentRunningSuite = this.rootSuite; + this.suitesStack = [this.rootSuite]; + } + + describe(desc, func) { + const configService = this.coreContext.getDefaultService('config'); + if (configService.filterSuite(desc)) { + console.info('filter suite :' + desc); + return; + } + const suite = new SuiteService.Suite({description: desc}); + if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') { + let suiteStress = this.coreContext.getServices('dataDriver').dataDriver.getSuiteStress(desc); + for (let i = 1; i < suiteStress; i++) { + this.currentRunningSuite.childSuites.push(suite); + } + } + this.currentRunningSuite.childSuites.push(suite); + this.currentRunningSuite = suite; + this.suitesStack.push(suite); + func.call(); + let childSuite = this.suitesStack.pop(); + if (this.suitesStack.length === 0) { + this.currentRunningSuite = childSuite; + this.suitesStack.push(childSuite); + } + if (this.suitesStack.length > 1) { + this.currentRunningSuite = this.suitesStack.pop(); + } else { + this.currentRunningSuite = this.suitesStack.pop(); + this.suitesStack.push(this.currentRunningSuite); + } + } + + beforeAll(func) { + this.currentRunningSuite.beforeAll.push(processFunc(this.coreContext, func)); + } + + beforeEach(func) { + this.currentRunningSuite.beforeEach.push(processFunc(this.coreContext, func)); + } + + afterAll(func) { + this.currentRunningSuite.afterAll.push(processFunc(this.coreContext, func)); + } + + afterEach(func) { + this.currentRunningSuite.afterEach.push(processFunc(this.coreContext, func)); + } + + getCurrentRunningSuite() { + return this.currentRunningSuite; + } + + setCurrentRunningSuite(suite) { + this.currentRunningSuite = suite; + } + + traversalResults(suite, obj, breakOnError) { + if (suite.childSuites.length === 0 && suite.specs.length === 0) { + return obj; + } + if (suite.specs.length > 0) { + for (const itItem of suite.specs) { + obj.total++; + if (breakOnError && (obj.error > 0 || obj.failure > 0)) { // breakOnError模式 + continue; + } + if (itItem.error) { + obj.error++; + } else if (itItem.result.failExpects.length > 0) { + obj.failure++; + } else if (itItem.result.pass === true) { + obj.pass++; + } + } + } + + obj.duration += suite.duration; + + if (suite.childSuites.length > 0) { + for (const suiteItem of suite.childSuites) { + this.traversalResults(suiteItem, obj, breakOnError); + } + } + } + + getSummary() { + let suiteService = this.coreContext.getDefaultService('suite'); + let rootSuite = suiteService.rootSuite; + const specService = this.coreContext.getDefaultService('spec'); + const configService = this.coreContext.getDefaultService('config'); + let breakOnError = configService.isBreakOnError(); + let isError = specService.getStatus(); + let isBreaKOnError = breakOnError && isError; + let obj = {total: 0, failure: 0, error: 0, pass: 0, ignore: 0, duration: 0}; + for (const suiteItem of rootSuite.childSuites) { + this.traversalResults(suiteItem, obj, isBreaKOnError); + } + obj.ignore = obj.total - obj.pass - obj.failure - obj.error; + return obj; + } + + init(coreContext) { + this.coreContext = coreContext; + } + + traversalSuites(suite, obj, configService) { + if (suite.childSuites.length === 0 && suite.specs.length === 0) { + return []; + } + if (suite.specs.length > 0) { + let itArray = []; + for (const itItem of suite['specs']) { + if (!configService.filterDesc(suite.description, itItem.description, itItem.fi, null)) { + itArray.push({'itName': itItem.description}); + } + } + obj[suite.description] = itArray; + } + + if (suite.childSuites.length > 0) { + let suiteArray = []; + for (const suiteItem of suite.childSuites) { + let suiteObj = {}; + this.traversalSuites(suiteItem, suiteObj, configService); + if (!configService.filterSuite(suiteItem.description)) { + suiteArray.push(suiteObj); + } + } + obj.suites = suiteArray; + } + } + + async dryRun(abilityDelegator) { + const configService = this.coreContext.getDefaultService('config'); + let testSuitesObj = {}; + let suitesArray = []; + for (const suiteItem of this.rootSuite.childSuites) { + let obj = {}; + this.traversalSuites(suiteItem, obj, configService); + if (!configService.filterSuite(suiteItem.description)) { + suitesArray.push(obj); + } + } + testSuitesObj['suites'] = suitesArray; + + let strJson = JSON.stringify(testSuitesObj); + let strLen = strJson.length; + let maxLen = 500; + let maxCount = Math.floor(strLen / maxLen); + + for (let count = 0; count <= maxCount; count++) { + await SysTestKit.print(strJson.substring(count * maxLen, (count + 1) * maxLen)); + } + console.info('dryRun print success'); + abilityDelegator.finishTest('dry run finished!!!', 0, () => { }); + } + + execute() { + const configService = this.coreContext.getDefaultService('config'); + if (configService.filterValid.length !== 0) { + this.coreContext.fireEvents('task', 'incorrectFormat'); + return; + } + + if (configService.isRandom() && this.rootSuite.childSuites.length > 0) { + this.rootSuite.childSuites.sort(function () { + return Math.random().toFixed(1) > 0.5 ? -1 : 1; + }); + this.currentRunningSuite = this.rootSuite.childSuites[0]; + } + + if (configService.isSupportAsync()) { + let asyncExecute = async () => { + await this.coreContext.fireEvents('task', 'taskStart'); + await this.rootSuite.asyncRun(this.coreContext); + }; + asyncExecute().then(async () => { + await this.coreContext.fireEvents('task', 'taskDone'); + }); + } else { + this.coreContext.fireEvents('task', 'taskStart'); + this.rootSuite.run(this.coreContext); + this.coreContext.fireEvents('task', 'taskDone'); + } + } + + apis() { + const _this = this; + return { + describe: function (desc, func) { + return _this.describe(desc, func); + }, + beforeAll: function (func) { + return _this.beforeAll(func); + }, + beforeEach: function (func) { + return _this.beforeEach(func); + }, + afterAll: function (func) { + return _this.afterAll(func); + }, + afterEach: function (func) { + return _this.afterEach(func); + } + }; + } +} + +SuiteService.Suite = class { + constructor(attrs) { + this.description = attrs.description || ''; + this.childSuites = []; + this.specs = []; + this.beforeAll = []; + this.afterAll = []; + this.beforeEach = []; + this.afterEach = []; + this.duration = 0; + } + + pushSpec(spec) { + this.specs.push(spec); + } + + removeSpec(desc) { + this.specs = this.specs.filter((item, index) => { + return item.description !== desc; + }); + } + + getSpecsNum() { + return this.specs.length; + } + + isRun(coreContext) { + const configService = coreContext.getDefaultService('config'); + const suiteService = coreContext.getDefaultService('suite'); + const specService = coreContext.getDefaultService('spec'); + let breakOnError = configService.isBreakOnError(); + let isError = specService.getStatus(); + return breakOnError && isError; + } + + run(coreContext) { + const suiteService = coreContext.getDefaultService('suite'); + suiteService.setCurrentRunningSuite(this); + if (this.description !== '') { + coreContext.fireEvents('suite', 'suiteStart', this); + } + this.runHookFunc('beforeAll'); + if (this.specs.length > 0) { + const configService = coreContext.getDefaultService('config'); + if (configService.isRandom()) { + this.specs.sort(function () { + return Math.random().toFixed(1) > 0.5 ? -1 : 1; + }); + } + for (let spec in this.specs) { + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + break; + } + this.runHookFunc('beforeEach'); + spec.run(coreContext); + this.runHookFunc('afterEach'); + } + } + if (this.childSuites.length > 0) { + for (let suite in this.childSuites) { + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + break; + } + suite.run(coreContext); + suiteService.setCurrentRunningSuite(suite); + } + } + this.runHookFunc('afterAll'); + if (this.description !== '') { + coreContext.fireEvents('suite', 'suiteDone'); + } + } + + async asyncRun(coreContext) { + const suiteService = coreContext.getDefaultService('suite'); + suiteService.setCurrentRunningSuite(this); + suiteService.suitesStack.push(this); + if (this.description !== '') { + await coreContext.fireEvents('suite', 'suiteStart', this); + } + await this.runAsyncHookFunc('beforeAll'); + if (this.specs.length > 0) { + const configService = coreContext.getDefaultService('config'); + if (configService.isRandom()) { + this.specs.sort(function () { + return Math.random().toFixed(1) > 0.5 ? -1 : 1; + }); + } + for (let i = 0; i < this.specs.length; i++) { + // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + console.log("break description :" + this.description); + break; + } + await this.runAsyncHookFunc('beforeEach'); + await this.specs[i].asyncRun(coreContext); + await this.runAsyncHookFunc('afterEach'); + } + } + + if (this.childSuites.length > 0) { + for (let i = 0; i < this.childSuites.length; i++) { + // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description + let isBreakOnError = this.isRun(coreContext); + if (isBreakOnError) { + console.log("break description :" + this.description); + break; + } + await this.childSuites[i].asyncRun(coreContext); + } + } + + await this.runAsyncHookFunc('afterAll'); + if (this.description !== '') { + await coreContext.fireEvents('suite', 'suiteDone'); + let childSuite = suiteService.suitesStack.pop(); + if (suiteService.suitesStack.length === 0) { + suiteService.suitesStack.push(childSuite); + } + if (suiteService.suitesStack.length > 1) { + suiteService.setCurrentRunningSuite(suiteService.suitesStack.pop()); + } else { + let currentRunningSuite = suiteService.suitesStack.pop(); + suiteService.setCurrentRunningSuite(currentRunningSuite); + suiteService.suitesStack.push(currentRunningSuite); + } + } + } + + runHookFunc(hookName) { + if (this[hookName] && this[hookName].length > 0) { + this[hookName].forEach(func => { + try { + func(); + } catch (e) { + console.error(e); + } + }); + } + } + + runAsyncHookFunc(hookName) { + if (this[hookName] && this[hookName].length > 0) { + return new Promise(async resolve => { + for (let i = 0; i < this[hookName].length; i++) { + try { + await this[hookName][i](); + } catch (e) { + console.error(e); + } + } + resolve(); + }); + } + } +}; + +class SpecService { + constructor(attr) { + this.id = attr.id; + this.totalTest = 0; + this.hasError = false; + } + + init(coreContext) { + this.coreContext = coreContext; + } + + setCurrentRunningSpec(spec) { + this.currentRunningSpec = spec; + } + + setStatus(obj) { + this.hasError = obj; + } + + getStatus() { + return this.hasError; + } + + getTestTotal() { + return this.totalTest; + } + + getCurrentRunningSpec() { + return this.currentRunningSpec; + } + + it(desc, filter, func) { + const configService = this.coreContext.getDefaultService('config'); + const currentSuiteName = this.coreContext.getDefaultService('suite').getCurrentRunningSuite().description; + if (configService.filterDesc(currentSuiteName, desc, filter, this.coreContext)) { + console.info('filter it :' + desc); + } else { + let processedFunc = processFunc(this.coreContext, func); + const spec = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc}); + const suiteService = this.coreContext.getDefaultService('suite'); + if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') { + let specStress = this.coreContext.getServices('dataDriver').dataDriver.getSpecStress(desc); + for (let i = 1; i < specStress; i++) { + this.totalTest++; + suiteService.getCurrentRunningSuite().pushSpec(spec); + } + } + + // dryRun 状态下不统计压力测试重复数据 + if (configService['dryRun'] !== 'true') { + let stress = configService.getStress(); // 命令配置压力测试 + console.info('stress length :' + stress); + for (let i = 1; i < stress; i++) { + this.totalTest++; + suiteService.getCurrentRunningSuite().pushSpec(spec); + } + } + this.totalTest++; + suiteService.getCurrentRunningSuite().pushSpec(spec); + } + } + + apis() { + const _this = this; + return { + it: function (desc, filter, func) { + return _this.it(desc, filter, func); + } + }; + } +} + +SpecService.Spec = class { + constructor(attrs) { + this.description = attrs.description || ''; + this.fi = attrs.fi; + this.fn = attrs.fn || function () { + }; + this.result = { + failExpects: [], + passExpects: [] + }; + this.error = undefined; + this.duration = 0; + this.startTime = 0; + this.isExecuted = false; // 当前用例是否执行 + } + + setResult(coreContext) { + const specService = coreContext.getDefaultService('spec'); + if (this.result.failExpects.length > 0) { + this.result.pass = false; + specService.setStatus(true); + } else { + this.result.pass = true; + } + console.info('testcase ' + this.description + ' result:' + this.result.pass); + } + + run(coreContext) { + const specService = coreContext.getDefaultService('spec'); + specService.setCurrentRunningSpec(this); + coreContext.fireEvents('spec', 'specStart', this); + this.isExecuted = true; + try { + let dataDriver = coreContext.getServices('dataDriver'); + if (typeof dataDriver === 'undefined') { + this.fn(); + } else { + let suiteParams = dataDriver.dataDriver.getSuiteParams(); + let specParams = dataDriver.dataDriver.getSpecParams(); + console.info('[suite params] ' + JSON.stringify(suiteParams)); + console.info('[spec params] ' + JSON.stringify(specParams)); + if (this.fn.length === 0) { + this.fn(); + } else if (specParams.length === 0) { + this.fn(suiteParams); + } else { + specParams.forEach(paramItem => this.fn(Object.assign({}, paramItem, suiteParams))); + } + } + this.setResult(coreContext); + } catch (e) { + this.error = e; + specService.setStatus(true); + } + coreContext.fireEvents('spec', 'specDone', this); + } + + async asyncRun(coreContext) { + const specService = coreContext.getDefaultService('spec'); + specService.setCurrentRunningSpec(this); + + await coreContext.fireEvents('spec', 'specStart', this); + try { + let dataDriver = coreContext.getServices('dataDriver'); + if (typeof dataDriver === 'undefined') { + await this.fn(); + this.setResult(coreContext); + } else { + let suiteParams = dataDriver.dataDriver.getSuiteParams(); + let specParams = dataDriver.dataDriver.getSpecParams(); + console.info('[suite params] ' + JSON.stringify(suiteParams)); + console.info('[spec params] ' + JSON.stringify(specParams)); + if (this.fn.length === 0) { + await this.fn(); + this.setResult(coreContext); + } else if (specParams.length === 0) { + await this.fn(suiteParams); + this.setResult(coreContext); + } else { + for (const paramItem of specParams) { + await this.fn(Object.assign({}, paramItem, suiteParams)); + this.setResult(coreContext); + } + } + } + } catch (e) { + if (e instanceof AssertException) { + this.fail = e; + specService.setStatus(true); + } else { + this.error = e; + specService.setStatus(true); + } + } + this.isExecuted = true; + await coreContext.fireEvents('spec', 'specDone', this); + } + + filterCheck(coreContext) { + const specService = coreContext.getDefaultService('spec'); + specService.setCurrentRunningSpec(this); + return true; + } + + addExpectationResult(expectResult) { + if (this.result.failExpects.length === 0) { + this.result.failExpects.push(expectResult); + } + throw new AssertException(expectResult.message); + } +}; + +class ExpectService { + constructor(attr) { + this.id = attr.id; + this.matchers = {}; + } + + expect(actualValue) { + return this.wrapMatchers(actualValue); + } + + init(coreContext) { + this.coreContext = coreContext; + this.addMatchers(this.basicMatchers()); + } + + addMatchers(matchers) { + for (const matcherName in matchers) { + if (Object.prototype.hasOwnProperty.call(matchers, matcherName)) { + this.matchers[matcherName] = matchers[matcherName]; + } + } + } + + basicMatchers() { + return { + assertTrue: function (actualValue) { + return { + pass: (actualValue) === true, + message: 'expect true, actualValue is ' + actualValue + }; + }, + assertEqual: function (actualValue, args) { + return { + pass: (actualValue) === args[0], + expectValue: args[0], + message: 'expect ' + actualValue + ' equals ' + args[0] + }; + }, + assertThrow: function (actual, args) { + const result = { + pass: false + }; + if (typeof actual !== 'function') { + result.message = 'toThrow\'s Actual should be a Function'; + } else { + let hasThrow = false; + let throwError; + try { + actual(); + } catch (e) { + hasThrow = true; + throwError = e; + } + if (!hasThrow) { + result.message = 'function did not throw an exception'; + } else if (throwError && throwError.message === args[0]) { + result.pass = true; + } else { + result.message = `expect to throw ${args[0]} , actual throw ${throwError.message}`; + } + } + return result; + } + }; + } + + wrapMatchers(actualValue) { + const _this = this; + const wrappedMatchers = { + // 翻转标识 + isNot: false, + + // 翻转方法 + not: function () { + this.isNot = true; + return this; + } + }; + const specService = _this.coreContext.getDefaultService('spec'); + const currentRunningSpec = specService.getCurrentRunningSpec(); + for (const matcherName in this.matchers) { + let result = Object.prototype.hasOwnProperty.call(this.matchers, matcherName); + if (!result) { + continue; + } + if (matcherName.search('assertPromise') == 0) { + wrappedMatchers[matcherName] = async function () { + await _this.matchers[matcherName](actualValue, arguments).then(function (result) { + if (wrappedMatchers.isNot) { + result.pass = !result.pass; + } + result.actualValue = actualValue; + result.checkFunc = matcherName; + if (!result.pass) { + currentRunningSpec.addExpectationResult(result); + } + }); + }; + } else { + wrappedMatchers[matcherName] = function () { + const result = _this.matchers[matcherName](actualValue, arguments); + if (wrappedMatchers.isNot) { + result.pass = !result.pass; + } + result.actualValue = actualValue; + result.checkFunc = matcherName; + if (!result.pass) { + currentRunningSpec.addExpectationResult(result); + } + }; + } + } + return wrappedMatchers; + } + + apis() { + const _this = this; + return { + expect: function (actualValue) { + return _this.expect(actualValue); + } + }; + } +} + +class ReportService { + constructor(attr) { + this.id = attr.id; + } + + init(coreContext) { + this.coreContext = coreContext; + this.specService = this.coreContext.getDefaultService('spec'); + this.suiteService = this.coreContext.getDefaultService('suite'); + this.duration = 0; + } + + taskStart() { + console.info('[start] start run suites'); + } + + async suiteStart() { + console.info('[suite start]' + this.suiteService.getCurrentRunningSuite().description); + } + + async specStart() { + console.info('start running case \'' + this.specService.currentRunningSpec.description + '\''); + this.index = this.index + 1; + let spec = this.specService.currentRunningSpec; + spec.startTime = await SysTestKit.getRealTime(); + } + + async specDone() { + let msg = ''; + let spec = this.specService.currentRunningSpec; + let suite = this.suiteService.currentRunningSuite; + spec.duration = await SysTestKit.getRealTime() - spec.startTime; + suite.duration += spec.duration; + if (spec.error) { + this.formatPrint('error', spec.description + ' ; consuming ' + spec.duration + 'ms'); + this.formatPrint('errorDetail', spec.error); + } else if (spec.result) { + if (spec.result.failExpects.length > 0) { + this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms'); + spec.result.failExpects.forEach(failExpect => { + msg = failExpect.message || ('expect ' + failExpect.actualValue + ' ' + + failExpect.checkFunc + ' ' + (failExpect.expectValue)); + this.formatPrint('failDetail', msg); + }); + } else { + this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms'); + } + } + this.formatPrint(this.specService.currentRunningSpec.error, msg); + } + + suiteDone() { + let suite = this.suiteService.currentRunningSuite; + console.info(`[suite end] ${suite.description} consuming ${suite.duration} ms`); + } + + taskDone() { + let msg = ''; + let summary = this.suiteService.getSummary(); + msg = 'total cases:' + summary.total + ';failure ' + summary.failure + ',' + 'error ' + summary.error; + msg += ',pass ' + summary.pass + '; consuming ' + summary.duration + 'ms'; + console.info(msg); + console.info('[end] run suites end'); + } + + incorrectFormat() { + if (this.coreContext.getDefaultService('config').filterValid.length !== 0) { + this.coreContext.getDefaultService('config').filterValid.forEach(function (item) { + console.info('this param ' + item + ' is invalid'); + }); + } + } + + formatPrint(type, msg) { + switch (type) { + case 'pass': + console.info('[pass]' + msg); + break; + case 'fail': + console.info('[fail]' + msg); + break; + case 'failDetail': + console.info('[failDetail]' + msg); + break; + case 'error': + console.info('[error]' + msg); + break; + case 'errorDetail': + console.info('[errorDetail]' + msg); + break; + } + } + + sleep(numberMillis) { + var now = new Date(); + var exitTime = now.getTime() + numberMillis; + while (true) { + now = new Date(); + if (now.getTime() > exitTime) { + return; + } + } + } +} + +export { + SuiteService, + SpecService, + ExpectService, + ReportService +}; diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..989c850d90269886e5bbab58d829e9ba7257ebe1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..989c850d90269886e5bbab58d829e9ba7257ebe1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4f86ec5788fae9bfb7c37a62e1fe493278c81e19 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "name": "path_provider", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_ohos.har" + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..28597a654670bde1dfe147bd6033286fa8f4f7b4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,237 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..2488a9b60779b2bca29714926c47f513fae7adb2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,169 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..0db841ed9cff9fdea904b802e68d01f1d9b2b36a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3517276bcfc5453175c8f9b532d32b71e7d0e76 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h new file mode 100644 index 0000000000000000000000000000000000000000..7804e730e1b4dbdb21b54729d5039a3f06d01347 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESOURCE_TABLE_H +#define RESOURCE_TABLE_H + +#include + +namespace OHOS { +const int32_t STRING_PAGE_SHOW = 0x01000000; +} +#endif \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..5fe3850329df700867f0f4692936181c9dd1f6b9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json @@ -0,0 +1,24 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "virtualMachine": "ark9.0.0.0", + "compileMode": "esmodule", + "dependencies": [] + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json new file mode 100644 index 0000000000000000000000000000000000000000..384d0290daf29cee301a5271dec2824791a3d614 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json @@ -0,0 +1,10 @@ +{ + "record" : + [ + { + "id" : "0x01000000", + "name" : "page_show", + "type" : "string" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..fd826dbf47a8c5bd149d62909693a88a3df49a52 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json @@ -0,0 +1,27 @@ +{ + "app" : + { + "apiReleaseType" : "Release", + "bundleName" : "io.flutter.plugins.pathprovider", + "compileSdkType" : "HarmonyOS", + "compileSdkVersion" : "4.0.0.40", + "debug" : true, + "minAPIVersion" : 40000010, + "targetAPIVersion" : 40000010, + "versionCode" : 1000000, + "versionName" : "1.0.0" + }, + "module" : + { + "compileMode" : "esmodule", + "dependencies" : [], + "deviceTypes" : + [ + "default", + "tablet" + ], + "name" : "path_provider", + "type" : "har", + "virtualMachine" : "ark9.0.0.0" + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..272edbc65fdba3d0fd4ba496cc6c181d0aebc721 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json @@ -0,0 +1 @@ +{"configPath":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","packageName":"io.flutter.plugins.pathprovider","output":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","moduleNames":"path_provider","ResourceTable":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h"],"moduleResources":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources"],"dependencies":[],"ids":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","definedIds":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json"} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index new file mode 100644 index 0000000000000000000000000000000000000000..3b7227cd2f2eb4b8f1ecc2cd52ad2411dd6f01d9 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..b49073ac77deb7ab1a4722ef4e4fb34a2bb57893 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..146d26c0fbde7fade1030172bc679b8f857a7490 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c5b4395b50fb6f82ab488221c479b7e39129de20 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_embedding.har" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159750ecea7bec636e067dea44f6b469601d685 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x02000000 \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..95e376706d75437dce67c79dfd886e97fa82f276 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + } + ], +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c96b70703b57d3e53a171aabf07727db248e94b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export { FlutterAbility } from './src/main/ets/embedding/ohos/FlutterAbility' + +export { FlutterPage } from './src/main/ets/embedding/ohos/FlutterPage' diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..2aa191e0adafd258a3aee290e137f579d35ec427 Binary files /dev/null and b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c4acdada0ca16f1a1a4ada0bda0b669a04062911 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "Apache-2.0", + "devDependencies": { + "@types/libflutter.so": "file:./src/main/cpp/types/libflutter" + }, + "author": "", + "name": "flutter_embedding", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..bb628633cdb60882359286a05a10befeb05427fc --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts @@ -0,0 +1,66 @@ +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import image from '@ohos.multimedia.image'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; + +export const getContext: (a: number) => napiContext; + +export class napiContext { + onPageShow(); + + onPageHide(); +} + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => {}; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + +export const nativeAttach: (napi: FlutterNapi) => number; + +export const nativeRunBundleAndSnapshotFromLibrary: ( + nativeShellHolderId: number, + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +//Send a data-carrying response to a platform message received from Dart. +export const nativeInvokePlatformMessageResponseCallback: (nativeShellHolderId: number, responseId: number, message: ArrayBuffer, position: number) => void; + +// Send an empty response to a platform message received from Dart. +export const nativeInvokePlatformMessageEmptyResponseCallback: (nativeShellHolderId: number, responseId: number) => void; + +// Send a data-carrying platform message to Dart. +export const nativeDispatchPlatformMessage: (nativeShellHolderId: number, channel: String, message: ArrayBuffer, position: number, responseId: number) => void; + +// Send an empty platform message to Dart. +export const nativeDispatchEmptyPlatformMessage: (nativeShellHolderId: number, channel: String, responseId: number) => void; + +export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array) => void; + +export const nativeImageDecodeCallback: (width: number, height: number, imageGeneratorPointer: number, pixelMap : image.PixelMap) => void; + +export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb1b4f1eb7f1eaf5f362ec2c66d225dd5dc1c240 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts @@ -0,0 +1,252 @@ +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import image from '@ohos.multimedia.image'; + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => void; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + + +/** + * 加载dart工程构建产物 + */ +export const nativeRunBundleAndSnapshotFromLibrary: ( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +/** + * 初始化SkFontMgr::RefDefault(),skia引擎文字管理初始化 + */ +export const nativePrefetchDefaultFontManager: () => void; + +/** + * 返回是否支持软件绘制 + */ +export const nativeGetIsSoftwareRenderingEnabled: () => boolean; + +/** + * attach flutterNapi实例给到 native engine,这个支持rkts到flutter平台的无关引擎之间的通信。 + * attach只需要执行一次 + */ +export const nativeAttach: (flutterNapi: FlutterNapi) => number; + +/** + * 从当前的flutterNapi复制一个新的实例 + */ +export const nativeSpawn: ( + nativeSpawningShellId: number, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + initialRoute: string, + entrypointArgs: Array +) => FlutterNapi; + +/** + * Detaches flutterNapi和engine之间的关联 + * 这个方法执行前提是flutterNapi已经和engine关联 + */ +export const nativeDestroy: ( + nativeShellHolderId: number +) => void; + +// 不需要实现,未使用到 +// export const nativeImageHeaderCallback: ( +// imageGeneratorPointer: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceCreated: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceWindowChanged: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceChanged: ( +// nativeShellHolderId: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceDestroyed: ( +// nativeShellHolderId: number +// ) => void; + +/** + * 把物理屏幕参数通知到native + */ +export const nativeSetViewportMetrics: ( + nativeShellHolderId: number, + devicePixelRatio: number, + physicalWidth: number, + physicalHeight: number, + physicalPaddingTop: number, + physicalPaddingRight: number, + physicalPaddingBottom: number, + physicalPaddingLeft: number, + physicalViewInsetTop: number, + physicalViewInsetRight: number, + physicalViewInsetBottom: number, + physicalViewInsetLeft: number, + systemGestureInsetTop: number, + systemGestureInsetRight: number, + systemGestureInsetBottom: number, + systemGestureInsetLeft: number, + physicalTouchSlop: number, + displayFeaturesBounds: Array, + displayFeaturesType: Array, + displayFeaturesState: Array +) => void; + +/** + * 设置能力参数 + */ +export const nativeSetAccessibilityFeatures: ( + nativeShellHolderId: number, + flags: number +) => void; + +/** + * 清除某个messageData + */ +export const nativeCleanupMessageData: ( + messageData: number +) => void; + +/** + * 发送一个空的PlatformMessage + */ +export const nativeDispatchEmptyPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + responseId: number +) => void; + +/** + * 发送一个PlatformMessage + */ +export const nativeDispatchPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + message: ArrayBuffer, + position: number, + responseId: number +) => void; + +/** + * 空的PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageEmptyResponseCallback: ( + nativeShellHolderId: number, + responseId: number +) => void; + +/** + * PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageResponseCallback: ( + nativeShellHolderId: number, + responseId: number, + message: ArrayBuffer, + position: number +) => void; + + +/** + * load一个合法的.so文件到dart vm + */ +export const nativeLoadDartDeferredLibrary: ( + nativeShellHolderId: number, + loadingUnitId: number, + searchPaths: Array +) => void; + +/** + * 设置ResourceManager和assetBundlePath到engine + */ +export const nativeUpdateOhosAssetManager: ( + nativeShellHolderId: number, + resourceManager: resourceManager.ResourceManager, + assetBundlePath: string +) => void; + +/** + * 加载动态库,或者dart库失败时的通知 + */ +export const nativeDeferredComponentInstallFailure: ( + loadingUnitId: number, + error: string, + isTransient: boolean +) => void; + +/** + * 从engine获取当前绘制pixelMap + */ +export const nativeGetPixelMap: () => image.PixelMap; + +/** + * 应用低内存警告 + */ +export const nativeNotifyLowMemoryWarning: ( + nativeShellHolderId: number +) => void; + +// ----- Start FlutterTextUtils Methods ---- +/** + * 下面的方法,从键盘输入中判断当前字符是否是emoji,实现优先级低 + */ +export const nativeFlutterTextUtilsIsEmoji: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifier: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifierBase: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsVariationSelector: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsRegionalIndicator: ( + codePoint: number +) => boolean; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0e11cf2c3c8aefb7ddcff477d21b2894d08b5520 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libflutter.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6f2f8b0e5dd765611d87ac3b2c2c552ff5adb2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from './embedding/engine/FlutterNapi'; +import FlutterLoader from './embedding/engine/loader/FlutterLoader'; + +/** + * flutter相关主要类的单例持有,帮助实现自身和其他类的实例化管理 + */ +export default class FlutterInjector { + private static instance: FlutterInjector; + + private flutterLoader: FlutterLoader; + private flutterNapi: FlutterNapi; + + static getInstance(): FlutterInjector { + if (FlutterInjector.instance == null) { + FlutterInjector.instance = new FlutterInjector(); + } + return FlutterInjector.instance; + } + /** + * 初始化 + */ + private constructor() { + this.flutterNapi = new FlutterNapi(); + this.flutterLoader = new FlutterLoader(this.flutterNapi); + } + + getFlutterLoader(): FlutterLoader { + return this.flutterLoader; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..77c89858b09535ee4b34af516b7eb18cb5d5a3ee --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets @@ -0,0 +1,34 @@ +import FlutterView from '../embedding/ohos/FlutterView'; +import common from '@ohos.app.ability.common'; +import PlatformViewController from '../plugin/platform/PlatformViewsController' +import Log from '../util/Log'; + +export default class FlutterPluginRegistry { + private mPlatformViewsController: PlatformViewController; + private mFlutterView: FlutterView; + private mContext: common.Context; + + constructor() { + this.mPlatformViewsController = new PlatformViewController(); + } + + attach(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mContext = context; + } + + detach(): void { + this.mPlatformViewsController.detach(); + this.mPlatformViewsController.onDetachedFromNapi(); + this.mFlutterView = null; + this.mContext = null; + } + + destroy(): void { + this.mPlatformViewsController.onDetachedFromNapi(); + } + + onPreEngineRestart(): void{ + this.mPlatformViewsController.onPreEngineRestart(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..07497e672b21c51727c1a45166504e19603e4063 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * 基础component,还未封装,看情况是否使用 + */ +@Component +export default struct FlutterComponent { + build() { + Row() { + Column() { + Text("xxx") + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a16a419d9c7a5df84379278cdc7fb113624d7f7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets @@ -0,0 +1,277 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LifecycleChannel from './systemchannels/LifecycleChannel'; +import DartExecutor, { DartEntrypoint } from './dart/DartExecutor'; +import FlutterShellArgs from './FlutterShellArgs'; +import FlutterInjector from '../../FlutterInjector'; +import FlutterLoader from './loader/FlutterLoader'; +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from './FlutterNapi'; +import NavigationChannel from './systemchannels/NavigationChannel'; +import Log from '../../util/Log'; +import TestChannel from './systemchannels/TestChannel' +import FlutterEngineConnectionRegistry from './FlutterEngineConnectionRegistry'; +import PluginRegistry from './plugins/PluginRegistry'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import TextInputChannel from './systemchannels/TextInputChannel'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import PlatformChannel from './systemchannels/PlatformChannel'; +import FlutterEngineGroup from './FlutterEngineGroup'; +import SystemChannel from './systemchannels/SystemChannel'; +import MouseCursorChannel from './systemchannels/MouseCursorChannel'; +import RestorationChannel from './systemchannels/RestorationChannel'; +import LocalizationChannel from './systemchannels/LocalizationChannel'; +import AccessibilityChannel from './systemchannels/AccessibilityChannel'; +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' +import SettingsChannel from './systemchannels/SettingsChannel'; +import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; + +const TAG = "FlutterEngine"; + +/** + * 操作FlutterEngin相关 + */ +export default class FlutterEngine implements EngineLifecycleListener{ + private engineLifecycleListeners = new Set(); + + dartExecutor: DartExecutor; + private flutterLoader: FlutterLoader; + private assetManager: resourceManager.ResourceManager; + //channel定义 + private lifecycleChannel: LifecycleChannel; + private navigationChannel: NavigationChannel; + private textInputChannel: TextInputChannel; + private testChannel: TestChannel; + private platformChannel: PlatformChannel; + private systemChannel: SystemChannel; + private mouseCursorChannel: MouseCursorChannel; + private restorationChannel: RestorationChannel; + + private accessibilityChannel: AccessibilityChannel; + private localeChannel: LocalizationChannel; + private flutterNapi: FlutterNapi; + private pluginRegistry: FlutterEngineConnectionRegistry; + private textInputPlugin: TextInputPlugin; + private localizationPlugin: LocalizationPlugin; + private settingsChannel: SettingsChannel; + private platformViewsController: PlatformViewsController; + + /** + * 需要初始化的工作: + * 1、初始化DartExecutor + * 2、初始化所有channel + * 3、初始化plugin + * 4、初始化flutterLoader + * 5、初始化flutterNapi + * 6、engineLifecycleListeners + */ + constructor(context: common.Context, flutterLoader: FlutterLoader, flutterNapi: FlutterNapi, platformViewsController: PlatformViewsController) { + const injector: FlutterInjector = FlutterInjector.getInstance(); + + if(flutterNapi == null){ + flutterNapi = FlutterInjector.getInstance().getFlutterNapi(); + } + this.flutterNapi = flutterNapi; + this.assetManager = context.resourceManager; + + this.dartExecutor = new DartExecutor(this.flutterNapi, this.assetManager); + this.dartExecutor.onAttachedToNAPI(); + + if(flutterLoader == null){ + flutterLoader = injector.getFlutterLoader(); + } + this.flutterLoader = flutterLoader; + + if(platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + this.platformViewsController = platformViewsController; + this.platformViewsController.attach(context, null, this.dartExecutor); + } + + async init(context: common.Context, dartVmArgs: Array, automaticallyRegisterPlugins: boolean, + waitForRestorationData: boolean, group: FlutterEngineGroup) { + if (!this.flutterNapi.isAttached()) { + await this.flutterLoader.startInitialization(context) + this.flutterLoader.ensureInitializationComplete(dartVmArgs); + } + //channel初始化 + this.lifecycleChannel = new LifecycleChannel(this.dartExecutor); + this.navigationChannel = new NavigationChannel(this.dartExecutor); + this.textInputChannel = new TextInputChannel(this.dartExecutor); + this.testChannel = new TestChannel(this.dartExecutor); + this.platformChannel = new PlatformChannel(this.dartExecutor); + this.systemChannel = new SystemChannel(this.dartExecutor); + this.mouseCursorChannel = new MouseCursorChannel(this.dartExecutor); + this.restorationChannel = new RestorationChannel(this.dartExecutor, waitForRestorationData); + this.settingsChannel = new SettingsChannel(this.dartExecutor); + + this.localeChannel = new LocalizationChannel(this.dartExecutor); + this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); + this.flutterNapi.addEngineLifecycleListener(this); + this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); + + // It should typically be a fresh, unattached NAPI. But on a spawned engine, the NAPI instance + // is already attached to a native shell. In that case, the Java FlutterEngine is created around + // an existing shell. + if (!this.flutterNapi.isAttached()) { + this.attachToNapi(); + } + + this.pluginRegistry = new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, this.flutterLoader, group); + this.localizationPlugin.sendLocaleToFlutter(); + } + + private attachToNapi(): void { + Log.d(TAG, "Attaching to NAPI."); + this.flutterNapi.attachToNative(); + + if (!this.isAttachedToNapi()) { + throw new Error("FlutterEngine failed to attach to its native Object reference."); + } + this.flutterNapi.setLocalizationPlugin(this.localizationPlugin); + } + + async spawn(context: common.Context, + dartEntrypoint: DartEntrypoint, + initialRoute: string, + dartEntrypointArgs: Array, + platformViewsController: PlatformViewsController, + automaticallyRegisterPlugins: boolean, waitForRestorationData: boolean) { + if (!this.isAttachedToNapi()) { + throw new Error( + "Spawn can only be called on a fully constructed FlutterEngine"); + } + + const newFlutterNapi = + this.flutterNapi.spawn( + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + initialRoute, + dartEntrypointArgs); + const flutterEngine = new FlutterEngine( + context, + null, + newFlutterNapi, + platformViewsController + ); + await flutterEngine.init(context, null, automaticallyRegisterPlugins, waitForRestorationData, null) + return flutterEngine + } + + private isAttachedToNapi(): boolean { + return this.flutterNapi.isAttached(); + } + + getLifecycleChannel(): LifecycleChannel { + return this.lifecycleChannel; + } + + getNavigationChannel(): NavigationChannel { + return this.navigationChannel; + } + + getTextInputChannel(): TextInputChannel { + return this.textInputChannel; + } + + getPlatformChannel(): PlatformChannel { + return this.platformChannel; + } + + getSystemChannel(): SystemChannel { + return this.systemChannel; + } + + getLocaleChannel(): LocalizationChannel { + return this.localeChannel; + } + + getMouseCursorChannel(): MouseCursorChannel { + return this.mouseCursorChannel; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor + } + + getPlugins(): PluginRegistry { + return this.pluginRegistry; + } + + getAbilityControlSurface(): AbilityControlSurface { + return this.pluginRegistry; + } + + getSettingsChannel() { + return this.settingsChannel; + } + + onPreEngineRestart(): void { + + } + + onEngineWillDestroy(): void { + + } + + addEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(listener); + } + + removeEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.delete(listener); + } + + destroy(): void { + Log.d(TAG, "Destroying."); + this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) + this.flutterNapi.removeEngineLifecycleListener(this); + this.pluginRegistry.detachFromAbility(); + this.platformViewsController.onDetachedFromNapi(); + } + + getRestorationChannel(): RestorationChannel{ + return this.restorationChannel; + } + + getAccessibilityChannel(): AccessibilityChannel { + return this.accessibilityChannel; + } + + getLocalizationPlugin(): LocalizationPlugin { + return this.localizationPlugin; + } + + getSystemLanguages(): void { + return this.flutterNapi.getSystemLanguages(); + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } +} + +export interface EngineLifecycleListener { + onPreEngineRestart(): void; + + onEngineWillDestroy(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..78db31cae3a9d154a09f9f85541115dc4452573f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from "./FlutterEngine" + +export default class FlutterEngineCache { + private static instance : FlutterEngineCache; + private cachedEngines: Map = new Map(); + + static getInstance(): FlutterEngineCache { + if (FlutterEngineCache.instance == null) { + FlutterEngineCache.instance = new FlutterEngineCache(); + } + return FlutterEngineCache.instance; + } + /** + * 返回engineId对应的FlutterEngine是否存在 + */ + contains(engineId: String) : boolean { + return this.cachedEngines.has(engineId); + } + + /** + * 返回engineId对应的FlutterEngine + */ + get(engineId: String) : FlutterEngine { + return this.cachedEngines.get(engineId); + } + /** + * 将传入的FlutterEngine与engineId放在缓存中 + */ + put(engineId :String, engine: FlutterEngine): void { + if(engine != null) { + this.cachedEngines.set(engineId, engine); + } else { + this.cachedEngines.delete(engineId); + } + } + /** + * 移除engineId对应的FlutterEngine + */ + remove(engineId: String) : void { + this.put(engineId, null); + } + + /** + * 移除cachedEngines所有中所有的FlutterEngine + */ + clear():void { + this.cachedEngines.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..7709ea8a31e98f794314a7e2f3b84e890f1eee9f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PluginRegistry from './plugins/PluginRegistry'; +import { FlutterAssets, FlutterPlugin, FlutterPluginBinding } from './plugins/FlutterPlugin'; +import FlutterEngine from './FlutterEngine'; +import AbilityAware from './plugins/ability/AbilityAware'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import { + AbilityPluginBinding, + WindowFocusChangedListener, + OnSaveStateListener, + NewWantListener +} from './plugins/ability/AbilityPluginBinding'; +import HashSet from '@ohos.util.HashSet'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import common from '@ohos.app.ability.common'; +import FlutterLoader from './loader/FlutterLoader'; +import Log from '../../util/Log'; +import ToolUtils from '../../util/ToolUtils'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import ExclusiveAppComponent from '../ohos/ExclusiveAppComponent'; +import FlutterEngineGroup from './FlutterEngineGroup'; + +const TAG = "FlutterEngineCxnRegstry"; + +export default class FlutterEngineConnectionRegistry implements PluginRegistry, AbilityControlSurface { + // PluginRegistry + private plugins = new Map(); + + // Standard FlutterPlugin + private flutterEngine: FlutterEngine; + private pluginBinding: FlutterPluginBinding; + + // AbilityAware + private abilityAwarePlugins = new Map(); + + private exclusiveAbility: ExclusiveAppComponent; + private abilityPluginBinding: FlutterEngineAbilityPluginBinding; + + constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader, group: FlutterEngineGroup) { + this.flutterEngine = flutterEngine; + this.pluginBinding = new FlutterPluginBinding(appContext, this.flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), group, this.flutterEngine.getPlatformViewsController()?.getRegistry()); + } + + add(plugin: FlutterPlugin): void { + try { + if (this.has(plugin.getUniqueClassName())) { + Log.w( + TAG, + "Attempted to register plugin (" + + plugin + + ") but it was " + + "already registered with this FlutterEngine (" + + this.flutterEngine + + ")."); + return; + } + + Log.w(TAG, "Adding plugin: " + plugin); + // Add the plugin to our generic set of plugins and notify the plugin + // that is has been attached to an engine. + this.plugins.set(plugin.getUniqueClassName(), plugin); + plugin.onAttachedToEngine(this.pluginBinding); + + // For AbilityAware plugins, add the plugin to our set of AbilityAware + // plugins, and if this engine is currently attached to an Ability, + // notify the AbilityAware plugin that it is now attached to an Ability. + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + const abilityAware: ESObject = plugin; + this.abilityAwarePlugins.set(plugin.getUniqueClassName(), abilityAware); + if (this.isAttachedToAbility()) { + abilityAware.onAttachedToAbility(this.abilityPluginBinding); + } + } + } finally { + + } + } + + addList(plugins: Set): void { + plugins.forEach(plugin => this.add(plugin)) + } + + has(pluginClassName: string): boolean { + return this.plugins.has(pluginClassName); + } + + get(pluginClassName: string): FlutterPlugin { + return this.plugins.get(pluginClassName); + } + + remove(pluginClassName: string): void { + const plugin = this.plugins.get(pluginClassName); + if (plugin == null) { + return; + } + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + if (this.isAttachedToAbility()) { + const abilityAware: ESObject = plugin; + abilityAware.onDetachedFromAbility(); + } + this.abilityAwarePlugins.delete(pluginClassName); + } + // Notify the plugin that is now detached from this engine. Then remove + // it from our set of generic plugins. + plugin.onDetachedFromEngine(this.pluginBinding); + this.plugins.delete(pluginClassName) + } + + removeList(pluginClassNames: Set): void { + pluginClassNames.forEach(plugin => this.remove(plugin)) + } + + removeAll(): void { + this.removeList(new Set(this.plugins.keys())); + this.plugins.clear(); + } + + private isAttachedToAbility(): boolean { + return this.exclusiveAbility != null; + } + + attachToAbility(exclusiveAbility: ExclusiveAppComponent): void { + if (this.exclusiveAbility != null) { + this.exclusiveAbility.detachFromFlutterEngine(); + } + // If we were already attached to an app component, detach from it. + this.detachFromAppComponent(); + this.exclusiveAbility = exclusiveAbility; + this.attachToAbilityInternal(exclusiveAbility.getAppComponent(),); + } + + detachFromAbility(): void { + if (this.isAttachedToAbility()) { + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onDetachedFromAbility()) + this.detachFromAbilityInternal(); + } else { + Log.e(TAG, "Attempted to detach plugins from an Ability when no Ability was attached."); + } + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.abilityPluginBinding.onNewWant(want, launchParams); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.abilityPluginBinding.onWindowFocusChanged(hasFocus); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + return this.abilityPluginBinding.onSaveState(reason, wantParam); + } + + private detachFromAppComponent(): void { + if (this.isAttachedToAbility()) { + this.detachFromAbility(); + } + } + + private attachToAbilityInternal(ability: UIAbility): void { + this.abilityPluginBinding = new FlutterEngineAbilityPluginBinding(ability); + // Notify all AbilityAware plugins that they are now attached to a new Ability. + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onAttachedToAbility(this.abilityPluginBinding)); + } + + private detachFromAbilityInternal(): void { + this.exclusiveAbility = null; + this.abilityPluginBinding = null; + } + + destroy(): void{ + this.detachFromAppComponent(); + // Remove all registered plugins. + this.removeAll(); + } +} + +class FlutterEngineAbilityPluginBinding implements AbilityPluginBinding { + private ability: UIAbility; + private onNewWantListeners = new HashSet(); + private onWindowFocusChangedListeners = new HashSet(); + private onSaveStateListeners = new HashSet(); + + constructor(ability: UIAbility) { + this.ability = ability; + + } + + getAbility(): UIAbility { + return this.ability; + } + + addOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.add(listener) + } + + removeOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.remove(listener) + } + + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.add(listener) + } + + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.remove(listener) + } + + addOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.add(listener) + } + + removeOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.remove(listener) + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.onNewWantListeners.forEach((listener, key) => { + listener.onNewWant(want, launchParams) + }); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.onWindowFocusChangedListeners.forEach((listener, key) => { + listener.onWindowFocusChanged(hasFocus) + }); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + this.onSaveStateListeners.forEach((listener, key) => { + listener.onSaveState(reason, wantParam) + }); + return AbilityConstant.OnSaveResult.ALL_AGREE; + } +} + +class DefaultFlutterAssets implements FlutterAssets { + private flutterLoader: FlutterLoader; + + constructor(flutterLoader: FlutterLoader) { + this.flutterLoader = flutterLoader; + } + + getAssetFilePathByName(assetFileName: string, packageName?: string): string { + return this.flutterLoader.getLookupKeyForAsset(assetFileName, packageName); + } + + getAssetFilePathBySubpath(assetSubpath: string, packageName?: string) { + return this.flutterLoader.getLookupKeyForAsset(assetSubpath, packageName); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets new file mode 100644 index 0000000000000000000000000000000000000000..05e35aec1b7b6f50ab8df336bdd69fbbe21febc8 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" +import common from '@ohos.app.ability.common' +import FlutterLoader from './loader/FlutterLoader' +import FlutterInjector from '../../FlutterInjector' +import { DartEntrypoint } from './dart/DartExecutor' +import PlatformViewsController from '../../plugin/platform/PlatformViewsController' +import ArrayList from '@ohos.util.ArrayList' + +export default class FlutterEngineGroup { + private activeEngines: ArrayList = new ArrayList(); + + constructor() { + + } + + async checkLoader(context: common.Context, args: Array) { + let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!loader.initialized) { + await loader.startInitialization(context.getApplicationContext()); + loader.ensureInitializationComplete(args); + } + } + + async createAndRunEngineByOptions(options: Options) { + let engine: FlutterEngine = null; + let context: common.Context = options.getContext(); + let dartEntrypoint: DartEntrypoint = options.getDartEntrypoint(); + let initialRoute: string = options.getInitialRoute(); + let dartEntrypointArgs: Array = options.getDartEntrypointArgs(); + let platformViewsController: PlatformViewsController = options.getPlatformViewsController(); + let automaticallyRegisterPlugins: boolean = options.getAutomaticallyRegisterPlugins(); + let waitForRestorationData: boolean = options.getWaitForRestorationData(); + + if (dartEntrypoint == null) { + dartEntrypoint = DartEntrypoint.createDefault(); + } + + if (platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + + if (this.activeEngines.length == 0) { + engine = this.createEngine(context, platformViewsController); + await engine.init(context, null, // String[]. The Dart VM has already started, this arguments will have no effect. + automaticallyRegisterPlugins, // boolean. + waitForRestorationData, // boolean. + this) + if (initialRoute != null) { + engine.getNavigationChannel().setInitialRoute(initialRoute); + } + } else { + engine = await this.activeEngines[0] + .spawn( + context, + dartEntrypoint, + initialRoute, + dartEntrypointArgs, + platformViewsController, + automaticallyRegisterPlugins, + waitForRestorationData); + } + this.activeEngines.add(engine); + + const engineToCleanUpOnDestroy = engine; + let listener: EngineLifecycleListener = new EngineLifecycleListenerImpl( + platformViewsController, + this.activeEngines, + engineToCleanUpOnDestroy); + engine.addEngineLifecycleListener(listener); + return engine; + } + + createEngine(context: common.Context, platformViewsController: PlatformViewsController): FlutterEngine { + return new FlutterEngine(context, null, null, platformViewsController); + } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private platformViewsController: PlatformViewsController; + private activeEngines: ArrayList = new ArrayList(); + private engine: FlutterEngine; + + constructor( + platformViewsController: PlatformViewsController, + activeEngines: ArrayList, + engine: FlutterEngine) { + this.platformViewsController = platformViewsController; + this.activeEngines = activeEngines; + this.engine = engine; + } + onPreEngineRestart(): void { + this.platformViewsController.onPreEngineRestart(); + } + onEngineWillDestroy(): void { + this.activeEngines.remove(this.engine); + } +} + +export class Options { + private context: common.Context; + private dartEntrypoint: DartEntrypoint; + private initialRoute: string; + private dartEntrypointArgs: Array; + private platformViewsController: PlatformViewsController; + private automaticallyRegisterPlugins: boolean = true; + private waitForRestorationData: boolean = false; + + constructor(context: common.Context) { + this.context = context; + } + + getContext(): common.Context { + return this.context; + } + + getDartEntrypoint(): DartEntrypoint { + return this.dartEntrypoint; + } + + getInitialRoute(): string { + return this.initialRoute; + } + + getDartEntrypointArgs(): Array { + return this.dartEntrypointArgs; + } + + getAutomaticallyRegisterPlugins(): boolean { + return this.automaticallyRegisterPlugins; + } + + getWaitForRestorationData(): boolean { + return this.waitForRestorationData; + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } + + setDartEntrypoint(dartEntrypoint: DartEntrypoint): Options { + this.dartEntrypoint = dartEntrypoint; + return this; + } + + setInitialRoute(initialRoute: string): Options { + this.initialRoute = initialRoute; + return this; + } + + setDartEntrypointArgs(dartEntrypointArgs: Array): Options { + this.dartEntrypointArgs = dartEntrypointArgs; + return this; + } + + setAutomaticallyRegisterPlugins(automaticallyRegisterPlugins: boolean): Options { + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + return this; + } + + setWaitForRestorationData(waitForRestorationData: boolean): Options { + this.waitForRestorationData = waitForRestorationData; + return this; + } + + setPlatformViewsController(platformViewsController: PlatformViewsController): Options { + this.platformViewsController = platformViewsController; + return this; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b251069ce950ee8a0fb3d2f08b723a2d1e6f78 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngineGroup from './FlutterEngineGroup'; + +export default class FlutterEngineGroupCache { + static readonly instance = new FlutterEngineGroupCache(); + + private cachedEngineGroups = new Map(); + + contains(engineGroupId: string): boolean { + return this.cachedEngineGroups.has(engineGroupId); + } + + get(engineGroupId: string): FlutterEngineGroup { + return this.cachedEngineGroups.get(engineGroupId); + } + + put(engineGroupId: string, engineGroup?: FlutterEngineGroup) { + if (engineGroup != null) { + this.cachedEngineGroups.set(engineGroupId, engineGroup); + } else { + this.cachedEngineGroups.delete(engineGroupId); + } + } + + clear(): void { + this.cachedEngineGroups.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets new file mode 100644 index 0000000000000000000000000000000000000000..902699e44c585b355df699b78cca69b58f021055 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import flutter from 'libflutter.so'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log'; +import resourceManager from '@ohos.resourceManager'; +import { PlatformMessageHandler } from './dart/PlatformMessageHandler'; +import { FlutterCallbackInformation } from '../../view/FlutterCallbackInformation'; +import image from '@ohos.multimedia.image'; +import { EngineLifecycleListener } from './FlutterEngine'; +import { ByteBuffer } from '../../util/ByteBuffer'; +import { Action } from '../../view/AccessibilityBridge' +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin'; +import i18n from '@ohos.i18n'; + +const TAG = "FlutterNapi"; + +enum ContextType { + APP_LIFECYCLE = 0, + JS_PAGE_LIFECYCLE, +} + +/** + * 提供arkTs的flutterNAPI接口 + */ +export default class FlutterNapi { + hasInit: boolean = false; + //是否已实现 + hasImplemented: boolean = false; + + nativeShellHolderId: number = null; + platformMessageHandler: PlatformMessageHandler; + private engineLifecycleListeners = new Set(); + accessibilityDelegate: AccessibilityDelegate; + localizationPlugin: LocalizationPlugin; + + /** + * 更新刷新率 + * @param rate + */ + updateRefreshRate(refreshRateFPS : number) { + flutter.nativeUpdateRefreshRate(refreshRateFPS); + } + + init(context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number) { + if (this.hasInit) { + throw Error("the engine has init"); + } + this.hasInit = true; + Log.w(TAG, "init: bundlePath=" + bundlePath + " appStoragePath=" + appStoragePath + " engineCachesPath=" + engineCachesPath + " args=" + JSON.stringify(args)); + flutter.nativeInit(context, args, bundlePath, appStoragePath, engineCachesPath, initTimeMillis); + } + + attachToNative(): void { + this.nativeShellHolderId = flutter.nativeAttach(this); + Log.w(TAG, "nativeShellHolderId=" + this.nativeShellHolderId); + } + + runBundleAndSnapshotFromLibrary( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array) { + Log.w(TAG, "init: bundlePath=" + bundlePath + " entrypointFunctionName=" + entrypointFunctionName + " pathToEntrypointFunction=" + pathToEntrypointFunction + " entrypointArgs=" + JSON.stringify(entrypointArgs)) + flutter.nativeRunBundleAndSnapshotFromLibrary(this.nativeShellHolderId, bundlePath, entrypointFunctionName, pathToEntrypointFunction, assetManager, entrypointArgs); + }; + + /** + * 当前so方法是否都实现 + * @returns + */ + checkImplemented(methodName: string = ""): boolean { + if (!this.hasImplemented) { + Log.e(TAG, "this method has not implemented -> " + methodName) + } + return this.hasImplemented; + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.ensureRunningOnMainThread(); + this.platformMessageHandler = platformMessageHandler; + } + + private ensureAttachedToNative(): void { + if (this.nativeShellHolderId == null) { + throw new Error( + "Cannot execute operation because FlutterNapi is not attached to native."); + } + } + + private nativeNotifyLowMemoryWarning(nativeShellHolderId: number): void { + + } + + static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation { + return null; + } + + notifyLowMemoryWarning(): void { + this.ensureRunningOnMainThread(); + this.ensureAttachedToNative(); + this.nativeNotifyLowMemoryWarning(this.nativeShellHolderId); + } + + isAttached(): boolean { + return this.nativeShellHolderId != null; + } + + private ensureRunningOnMainThread(): void { + + } + + dispatchEmptyPlatformMessage(channel: String, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + flutter.nativeDispatchEmptyPlatformMessage(this.nativeShellHolderId, channel, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + /** Sends a reply {@code message} from Android to Flutter over the given {@code channel}. */ + dispatchPlatformMessage(channel: String, message: ArrayBuffer, position: number, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + + const uintArrayBuff = new Uint8Array(message) + let text = '' + for (let i = 0; i < uintArrayBuff.byteLength; i++) { + text += uintArrayBuff[i] + ',' + } + Log.w(TAG, "message=" + message.byteLength + ",text=" + text); + flutter.nativeDispatchPlatformMessage(this.nativeShellHolderId, channel, message, position, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + invokePlatformMessageEmptyResponseCallback(responseId: number): void { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageEmptyResponseCallback(this.nativeShellHolderId, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + invokePlatformMessageResponseCallback(responseId: number, message: ArrayBuffer, position: number) { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageResponseCallback( + this.nativeShellHolderId, responseId, message, position); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setViewportMetrics(devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array): void { + if (this.isAttached()) { + flutter.nativeSetViewportMetrics(this.nativeShellHolderId, devicePixelRatio, + physicalWidth, + physicalHeight, + physicalPaddingTop, + physicalPaddingRight, + physicalPaddingBottom, + physicalPaddingLeft, + physicalViewInsetTop, + physicalViewInsetRight, + physicalViewInsetBottom, + physicalViewInsetLeft, + systemGestureInsetTop, + systemGestureInsetRight, + systemGestureInsetBottom, + systemGestureInsetLeft, + physicalTouchSlop, + displayFeaturesBounds, + displayFeaturesType, + displayFeaturesState); + } + } + + spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array): FlutterNapi { + return new FlutterNapi(); + } + + addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(engineLifecycleListener); + } + + removeEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener) { + this.engineLifecycleListeners.delete(engineLifecycleListener); + } + + //Called by native to respond to a platform message that we sent. + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.w(TAG, "called handlePlatformMessageResponse Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handlePlatformMessageResponse(replyId, reply); + } + } + + // Called by native on any thread. + handlePlatformMessage(channel: string, message: ArrayBuffer, replyId: number, messageData: number): void { + Log.w(TAG, "called handlePlatformMessage Channel: " + channel + ". Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handleMessageFromDart(channel, message, replyId, messageData); + } + } + + // Called by native to notify first Flutter frame rendered. + onFirstFrame(): void { + Log.d(TAG, "called onFirstFrame") + } + + // Called by native. + onPreEngineRestart(): void { + Log.d(TAG, "called onPreEngineRestart") + this.engineLifecycleListeners.forEach( listener => listener.onPreEngineRestart()); + } + + // /** Invoked by native to obtain the results of OHOS's locale resolution algorithm. */ + computePlatformResolvedLocale(strings: Array): Array { + Log.d(TAG, "called computePlatformResolvedLocale " + JSON.stringify(strings)) + return [] + } + + decodeImage(buffer: ArrayBuffer, imageGeneratorAddress: number): void { + Log.d(TAG, "called decodeImage=" + buffer.byteLength) + const imageSourceApi = image.createImageSource(buffer); + let tempPixelMap: image.PixelMap = null; + imageSourceApi.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }).then(pixelMap => { + Log.d(TAG, "called createPixelMap end " + pixelMap.getPixelBytesNumber()) + tempPixelMap = pixelMap + return pixelMap.getImageInfo() + }).then(imageInfo => { + Log.d(TAG, `nativeImageHeaderCallback width=${imageInfo.size.width} height=${imageInfo.size.height} imageGeneratorAddress=${imageGeneratorAddress}`) + flutter.nativeImageDecodeCallback(imageInfo.size.width, imageInfo.size.height, imageGeneratorAddress, tempPixelMap) + }).catch((error: ESObject) => { + Log.d(TAG, "decodeImage error=" + JSON.stringify(error)) + flutter.nativeImageDecodeCallback(0, 0, imageGeneratorAddress, null); + }) + } + + setSemanticsEnabled(enabled: boolean, responseId: number): void { + if (this.isAttached()) { + this.nativeSetSemanticsEnabled(enabled); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + // Send an empty response to a platform message received from Dart. + nativeSetSemanticsEnabled(enabled: boolean):void {} + + setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { + if (this.isAttached()) { + this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeSetAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void {} + + dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { + if (this.isAttached()) { + this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeDispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void {} + + setAccessibilityDelegate(delegate: AccessibilityDelegate, responseId: number): void { + if (this.isAttached()) { + this.accessibilityDelegate = delegate; + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setLocalizationPlugin(localizationPlugin: LocalizationPlugin): void { + this.localizationPlugin = localizationPlugin; + } + + /** + * 获取系统语言列表 + * @param rate + */ + getSystemLanguages() { + Log.d(TAG, "called getSystemLanguages ") + let index: number; + let systemLanguages = i18n.System.getPreferredLanguageList(); + for (index = 0; index < systemLanguages.length; index++) { + Log.d(TAG, "systemlanguages "+ index + ":" + systemLanguages[index]); + } + flutter.nativeGetSystemLanguages(this.nativeShellHolderId, systemLanguages); + } +} + +export interface AccessibilityDelegate { + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void; + + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d63d83de313f52eba3f8fa6d2ed584f7bee44bd --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterOverlaySurface { + + private id: number; + + constructor(id: number) { + this.id = id + } + + getId(): number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a3cd75a49b7c53742072aa30541204060fc82e6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Want from '@ohos.app.ability.Want'; + +/** + * 封装flutter shell的参数 + */ +export default class FlutterShellArgs { + static ARG_KEY_TRACE_STARTUP = "trace-startup"; + static ARG_TRACE_STARTUP = "--trace-startup"; + static ARG_KEY_START_PAUSED = "start-paused"; + static ARG_START_PAUSED = "--start-paused"; + static ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; + static ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; + static ARG_KEY_ENDLESS_TRACE_BUFFER = "endless-trace-buffer"; + static ARG_ENDLESS_TRACE_BUFFER = "--endless-trace-buffer"; + static ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; + static ARG_USE_TEST_FONTS = "--use-test-fonts"; + static ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; + static ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; + static ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; + static ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; + static ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; + static ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; + static ARG_KEY_TRACE_SKIA = "trace-skia"; + static ARG_TRACE_SKIA = "--trace-skia"; + static ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; + static ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; + static ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; + static ARG_TRACE_SYSTRACE = "--trace-systrace"; + static ARG_KEY_ENABLE_IMPELLER = "enable-impeller"; + static ARG_ENABLE_IMPELLER = "--enable-impeller"; + static ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "dump-skp-on-shader-compilation"; + static ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "--dump-skp-on-shader-compilation"; + static ARG_KEY_CACHE_SKSL = "cache-sksl"; + static ARG_CACHE_SKSL = "--cache-sksl"; + static ARG_KEY_PURGE_PERSISTENT_CACHE = "purge-persistent-cache"; + static ARG_PURGE_PERSISTENT_CACHE = "--purge-persistent-cache"; + static ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; + static ARG_VERBOSE_LOGGING = "--verbose-logging"; + static ARG_KEY_OBSERVATORY_PORT = "observatory-port"; + static ARG_OBSERVATORY_PORT = "--observatory-port="; + static ARG_KEY_DART_FLAGS = "dart-flags"; + static ARG_DART_FLAGS = "--dart-flags"; + static ARG_KEY_MSAA_SAMPLES = "msaa-samples"; + static ARG_MSAA_SAMPLES = "--msaa-samples"; + + /** + * 从意图中解析参数,创建shellArgs + * @returns + */ + static fromWant(want: Want): FlutterShellArgs { + //tdo 解析want + return new FlutterShellArgs(); + } + + //参数 + args: Set = new Set(); + + add(arg: string) { + this.args.add(arg); + } + + remove(arg: string) { + this.args.delete(arg); + } + + toArray(): Array { + return Array.from(this.args); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ecfc7d5ef46c57923679789eb82f86eb83ef77 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default interface ExclusiveAppComponent { + /** + * Called when another App Component is about to become attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} this App Component is currently attached to. + * + *

This App Component's connections to the {@link io.flutter.embedding.engine.FlutterEngine} + * are still valid at the moment of this call. + */ + detachFromFlutterEngine(): void; + + /** + * Retrieve the App Component behind this exclusive App Component. + * + * @return The app component. + */ + getAppComponent(): T; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..07a374a7109e9a1ffcd5680220534c9796681e64 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -0,0 +1,414 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import window from '@ohos.window'; +import { FlutterAbilityDelegate, Host } from './FlutterAbilityDelegate'; +import Log from '../../util/Log'; +import FlutterEngine from '../engine/FlutterEngine'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import common from '@ohos.app.ability.common'; +import Want from '@ohos.app.ability.Want'; +import display from '@ohos.display'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import { AsyncCallback } from '@ohos.base'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import I18n from '@ohos.i18n' +import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; +import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; +import { DVModelContainer } from '../../view/DynamicView/dynamicView'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { Configuration } from '@ohos.app.ability.Configuration'; + +const TAG = "FlutterAbility"; +/** + * flutter ohos基础ability,请在让主ability继承自该类。 + * 该类主要职责: + * 1、持有FlutterAbilityDelegate并初始化; + * 2、生命周期传递; + */ +export class FlutterAbility extends UIAbility implements Host { + private delegate: FlutterAbilityDelegate; + private windowStage: window.WindowStage; + private mainWindow: window.Window; + private viewportMetrics = new ViewportMetrics(); + private displayInfo: display.Display; + + /** + * onCreate + * 1、create and attach delegate + * 2、config windows transparent noNeed? + * 3、lifecycle.onCreate + * 4. setContentView() noNeed + */ + async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + Log.i(TAG, "bundleCodeDir=" + this.context.bundleCodeDir); + // globalThis.flutterAbility = this + this.displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = this.displayInfo.densityPixels + + this.delegate = new FlutterAbilityDelegate(this); + await this.delegate.onAttach(this.context); + Log.i(TAG, 'onAttach end'); + this.delegate.platformPlugin.setUIAbilityContext(this.context); + this.delegate.onRestoreInstanceState(want); + this.delegate.sendSettings(); + + if (this.stillAttachedForEvent("onCreate")) { + this.delegate.onCreate(); + } + + console.log('MyAbility onCreate'); + // globalThis.applicationContext = this.context.getApplicationContext(); + } + + onDestroy() { + if (this.stillAttachedForEvent("onDestroy")) { + this.delegate.onDestroy(); + } + } + + /** + * window状态改变回调 + * @param windowStage + */ + async onWindowStageCreate(windowStage: window.WindowStage) { + this.windowStage = windowStage + try { + windowStage.on('windowStageEvent', (data) => { + let stageEventType: window.WindowStageEventType = data; + switch (stageEventType) { + case window.WindowStageEventType.SHOWN: // 切到前台 + Log.i(TAG, 'windowStage foreground.'); + break; + case window.WindowStageEventType.ACTIVE: // 获焦状态 + Log.i(TAG, 'windowStage active.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(true); + } + break; + case window.WindowStageEventType.INACTIVE: // 失焦状态 + Log.i(TAG, 'windowStage inactive.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(false); + } + break; + case window.WindowStageEventType.HIDDEN: // 切到后台 + Log.i(TAG, 'windowStage background.'); + break; + default: + break; + } + }); + + this.mainWindow = windowStage.getMainWindowSync() + this.mainWindow.on('windowSizeChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('avoidAreaChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('keyboardHeightChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.loadContent(); + this.mainWindow.setWindowLayoutFullScreen(true); + } catch (exception) { + Log.e(TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception)); + } + } + + loadContent() { + if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { + Log.i(TAG, 'loadContent'); + this.windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Log.e(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + this.onWindowPropertiesUpdated(); + Log.i(TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + if (this.stillAttachedForEvent("onWindowStageCreate")) { + this.delegate.onWindowStageCreate(); + } + this.delegate.getFlutterNapi().updateRefreshRate(this.displayInfo.refreshRate) + this.onFlutterEngineReady() + } + } + + onFlutterEngineReady(): void { + + } + + private updateViewportMetrics() { + this.delegate.getFlutterNapi().setViewportMetrics(this.viewportMetrics.devicePixelRatio, + this.viewportMetrics.physicalWidth, + this.viewportMetrics.physicalHeight, + this.viewportMetrics.physicalViewPaddingTop, + this.viewportMetrics.physicalViewPaddingRight, + this.viewportMetrics.physicalViewPaddingBottom, + this.viewportMetrics.physicalViewPaddingLeft, + this.viewportMetrics.physicalViewInsetTop, + this.viewportMetrics.physicalViewInsetRight, + this.viewportMetrics.physicalViewInsetBottom, + this.viewportMetrics.physicalViewInsetLeft, + this.viewportMetrics.systemGestureInsetTop, + this.viewportMetrics.systemGestureInsetRight, + this.viewportMetrics.systemGestureInsetBottom, + this.viewportMetrics.systemGestureInsetLeft, + this.viewportMetrics.physicalTouchSlop, + new Array(0), + new Array(0), + new Array(0)) + } + + onWindowStageDestroy() { + if (this.stillAttachedForEvent("onWindowStageDestroy")) { + this.delegate.onWindowStageDestroy(); + } + } + + onForeground() { + if (this.stillAttachedForEvent("onForeground")) { + this.delegate.onForeground(); + } + } + + onBackground() { + if (this.stillAttachedForEvent("onBackground")) { + this.delegate.onBackground(); + } + } + + release() { + if (this.delegate != null) { + this.delegate.release(); + this.delegate = null; + } + } + + /** + * host所有实现方法开始======start + */ + + getAbility(): UIAbility { + return this; + } + + shouldDispatchAppLifecycleState(): boolean { + return true; + } + + provideFlutterEngine(context: common.Context): FlutterEngine { + return null; + } + + configureFlutterEngine(flutterEngine: FlutterEngine) { + + } + + cleanUpFlutterEngine(flutterEngine: FlutterEngine) { + + } + + getFlutterShellArgs(): FlutterShellArgs { + return FlutterShellArgs.fromWant(this.getWant()); + } + + getDartEntrypointArgs(): Array { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; + } + return new Array() + } + + detachFromFlutterEngine() { + if (this.delegate != null) { + this.delegate.onDetach(); + } + } + + popSystemNavigator(): boolean { + return false; + } + + shouldAttachEngineToActivity(): boolean { + return true; + } + + getDartEntrypointLibraryUri(): string { + return null; + } + + getAppBundlePath(): string { + return null; + } + + getDartEntrypointFunctionName(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; + } + return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT + } + + getInitialRoute(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string; + } + return null + } + + getWant(): Want { + return this.launchWant; + } + + shouldDestroyEngineWithHost(): boolean { + return true; + } + + shouldRestoreAndSaveState(): boolean{ + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; + } + if (this.getCachedEngineId() != null) { + // Prevent overwriting the existing state in a cached engine with restoration state. + return false; + } + return true; + } + + getCachedEngineId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string + } + + getCachedEngineGroupId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string + } + + /** + * host所有实现方法结束======end + */ + private stillAttachedForEvent(event: string) { + Log.i(TAG, 'Ability ' + event); + if (this.delegate == null) { + Log.w(TAG, "FlutterAbility " + event + " call after release."); + return false; + } + if (!this.delegate.isAttached) { + Log.w(TAG, "FlutterAbility " + event + " call after detach."); + return false; + } + return true; + } + + addPlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.addPlugin(plugin) + } + } + + removePlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.removePlugin(plugin) + } + } + + private onWindowPropertiesUpdated(){ + if (!this.delegate.isAttached) { + return; + } + let systemAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let gestureAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + let keyboardAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + const properties = this.mainWindow.getWindowProperties(); + this.viewportMetrics.physicalWidth = properties.windowRect.width; + this.viewportMetrics.physicalHeight = properties.windowRect.height; + + this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea.topRect.height + this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea.leftRect.width + this.viewportMetrics.physicalViewPaddingBottom = systemAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea.rightRect.width + + this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea.topRect.height + this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea.leftRect.width + this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea.rightRect.width + + this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea.topRect.height + this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea.leftRect.width + this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea.bottomRect.height + this.viewportMetrics.systemGestureInsetRight = gestureAvoidArea.rightRect.width + + this.updateViewportMetrics() + } + + onMemoryLevel(level: AbilityConstant.MemoryLevel): void { + Log.i(TAG, 'onMemoryLevel: ' + level); + if (level === AbilityConstant.MemoryLevel.MEMORY_LEVEL_CRITICAL) { + this.delegate.onLowMemory(); + } + } + + onConfigurationUpdated(config: Configuration){ + Log.i(TAG, 'onConfigurationUpdated config:' + JSON.stringify(config)); + this.delegate.flutterEngine.getSettingsChannel().startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK + ? PlatformBrightness.LIGHT : PlatformBrightness.DARK); + } + + getWindowId(callback: AsyncCallback): void { + if (callback === null) { + return; + } + try { + window.getLastWindow(this.context, (error, win) => { + if (error.code) { + callback(error, -1); + return; + } + let windowId = win.getWindowProperties().id; + callback(error, windowId); + }); + } catch (err) { + Log.e(TAG, "get window id error!"); + callback(err, -1); + } + } +} + +export class ViewportMetrics { + devicePixelRatio: number = 1.0; + physicalWidth: number = 0; + physicalHeight: number = 0; + physicalViewPaddingTop: number = 0; + physicalViewPaddingRight: number = 0; + physicalViewPaddingBottom: number = 0; + physicalViewPaddingLeft: number = 0; + physicalViewInsetTop: number = 0; + physicalViewInsetRight: number = 0; + physicalViewInsetBottom: number = 0; + physicalViewInsetLeft: number = 0; + systemGestureInsetTop: number = 0; + systemGestureInsetRight: number = 0; + systemGestureInsetBottom: number = 0; + systemGestureInsetLeft: number = 0; + physicalTouchSlop = -1; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9046981a47219a7eb553dd4d3baeefa639069281 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import FlutterEngineConfigurator from './FlutterEngineConfigurator'; +import FlutterEngineProvider from './FlutterEngineProvider'; +import FlutterEngine from '../engine/FlutterEngine'; +import PlatformPlugin, { PlatformPluginDelegate } from '../../plugin/PlatformPlugin'; +import Want from '@ohos.app.ability.Want'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import DartExecutor, { DartEntrypoint } from '../engine/dart/DartExecutor'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import Log from '../../util/Log'; +import FlutterInjector from '../../FlutterInjector'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from './ExclusiveAppComponent'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import FlutterEngineCache from '../engine/FlutterEngineCache'; +import FlutterEngineGroupCache from '../engine/FlutterEngineGroupCache'; +import FlutterEngineGroup, { Options } from '../engine/FlutterEngineGroup'; +import MouseCursorPlugin, { MouseCursorViewDelegate } from '../../plugin/mouse/MouseCursorPlugin'; +import Settings from './Settings'; + +const TAG = "FlutterAbilityDelegate"; +const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; +const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; + +/** + * 主要职责: + * 1、初始化engine + * 2、处理ability生命周期回调 + */ +class FlutterAbilityDelegate implements ExclusiveAppComponent { + private host: Host; + flutterEngine: FlutterEngine; + platformPlugin: PlatformPlugin; + private context: common.Context; + private textInputPlugin: TextInputPlugin; + private isFlutterEngineFromHost: boolean; + private engineGroup: FlutterEngineGroup; + private mouseCursorPlugin: MouseCursorPlugin; + private settings: Settings; + + constructor(host: Host) { + this.host = host; + } + + /** + * 是否还attach在ability上 + */ + isAttached = false; + + async onAttach(context: common.Context): Promise { + this.context = context; + this.ensureAlive(); + if (this.flutterEngine == null) { + await this.setupFlutterEngine(); + } + //shouldAttachEngineToActivity + if (this.host.shouldAttachEngineToActivity()) { + // Notify any plugins that are currently attached to our FlutterEngine that they + // are now attached to an Ability. + Log.d(TAG, "Attaching FlutterEngine to the Ability that owns this delegate."); + this.flutterEngine.getAbilityControlSurface().attachToAbility(this); + } + + //providePlatformPlugin + + //configureFlutterEngine + this.isAttached = true; + Log.d(TAG, "onAttach end start loadcontent") + this.host.loadContent() + this.textInputPlugin = new TextInputPlugin(this.flutterEngine.getTextInputChannel()); + this.platformPlugin = new PlatformPlugin(this.flutterEngine.getPlatformChannel(), this.context); + this.mouseCursorPlugin = new MouseCursorPlugin(this.host, this.flutterEngine.getMouseCursorChannel()); + this.settings = new Settings(this.flutterEngine.getSettingsChannel()); + this.flutterEngine.getSystemLanguages(); + } + + /** + * 加载app.so资源或者snapshot + */ + private doInitialFlutterViewRun(): void { + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + const libraryUri = this.host.getDartEntrypointLibraryUri(); + Log.d(TAG, "Executing Dart entrypoint: " + this.host.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); + + // The engine needs to receive the Flutter app's initial route before executing any + // Dart code to ensure that the initial route arrives in time to be applied. + this.flutterEngine.getNavigationChannel().setInitialRoute(initialRoute); + + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride == '') { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint: DartEntrypoint = new DartEntrypoint( + appBundlePathOverride, + this.host.getDartEntrypointLibraryUri(), + this.host.getDartEntrypointFunctionName() + ); + this.flutterEngine.dartExecutor.executeDartEntrypoint(dartEntrypoint, this.host.getDartEntrypointArgs()); + } + + private maybeGetInitialRouteFromIntent(want: Want): string { + return null; + } + + + /** + * 通过参数,配置flutterEngine + * @param want + */ + onRestoreInstanceState(want: Want) { + let frameworkState: Uint8Array = want.parameters[FRAMEWORK_RESTORATION_BUNDLE_KEY] as Uint8Array; + if (this.host.shouldRestoreAndSaveState()) { + this.flutterEngine.getRestorationChannel().setRestorationData(frameworkState ?? null); + } + } + + /** + * 初始化flutterEngine + */ + async setupFlutterEngine() { + // First, check if the host wants to use a cached FlutterEngine. + const cachedEngineId = this.host.getCachedEngineId(); + Log.d(TAG, "cachedEngineId=" + cachedEngineId); + if (cachedEngineId && cachedEngineId.length > 0) { + this.flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); + this.isFlutterEngineFromHost = true; + if (this.flutterEngine == null) { + throw new Error( + "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" + + cachedEngineId + + "'"); + } + return; + } + + // Second, defer to subclasses for a custom FlutterEngine. + this.flutterEngine = this.host.provideFlutterEngine(this.context); + if (this.flutterEngine != null) { + this.isFlutterEngineFromHost = true; + return; + } + + // Third, check if the host wants to use a cached FlutterEngineGroup + // and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine + const cachedEngineGroupId = this.host.getCachedEngineGroupId(); + Log.d(TAG, "cachedEngineGroupId=" + cachedEngineGroupId); + if (cachedEngineGroupId != null) { + const flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); + if (flutterEngineGroup == null) { + throw new Error( + "The requested cached FlutterEngineGroup did not exist in the FlutterEngineGroupCache: '" + + cachedEngineGroupId + + "'"); + } + + this.flutterEngine = await flutterEngineGroup.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context))); + this.isFlutterEngineFromHost = false; + return; + } + + // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our + // FlutterView. + Log.d( + TAG, + "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); + + let group = this.engineGroup; + if (group == null) { + group = new FlutterEngineGroup(); + await group.checkLoader(this.context, this.host.getFlutterShellArgs().toArray()); + } + this.flutterEngine = await group.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context) + .setAutomaticallyRegisterPlugins(false).setWaitForRestorationData(this.host.shouldRestoreAndSaveState()))); + this.isFlutterEngineFromHost = false; + } + + addEntrypointOptions(options: Options): Options { + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride.length == 0) { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint = new DartEntrypoint(appBundlePathOverride, null, this.host.getDartEntrypointFunctionName()); + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + return options + .setDartEntrypoint(dartEntrypoint) + .setInitialRoute(initialRoute) + .setDartEntrypointArgs(this.host.getDartEntrypointArgs()); + } + + /** + * 释放所有持有对象 + */ + release() { + this.host = null; + this.flutterEngine = null; + } + + onDetach() { + if (this.host.shouldAttachEngineToActivity()) { + // Notify plugins that they are no longer attached to an Activity. + Log.d(TAG, "Detaching FlutterEngine from the Ability"); + this.flutterEngine.getAbilityControlSurface().detachFromAbility(); + } + } + + onLowMemory(): void { + this.getFlutterNapi().notifyLowMemoryWarning(); + this.flutterEngine.getSystemChannel().sendMemoryPressureWarning(); + } + + /** + * 生命周期回调 + */ + + onCreate() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsInactive(); + } + } + + onDestroy() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsDetached(); + } + this.textInputPlugin.detach(); + } + + onWindowStageCreate() { + this.ensureAlive(); + this.doInitialFlutterViewRun(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onWindowStageDestroy() { + + } + + onWindowFocusChanged(hasFocus: boolean):void { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getAbilityControlSurface().onWindowFocusChanged(hasFocus); + if (hasFocus) { + this.flutterEngine.getLifecycleChannel().aWindowIsFocused(); + } else { + this.flutterEngine.getLifecycleChannel().noWindowsAreFocused(); + } + } + } + + onForeground() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onBackground() { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsPaused(); + } + } + + /** + * 生命周期回调结束 + */ + + shouldDispatchAppLifecycleState(): boolean { + return this.host.shouldDispatchAppLifecycleState() && this.isAttached; + } + + ensureAlive() { + if (this.host == null) { + throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); + } + } + + getFlutterNapi() { + return this.flutterEngine.getFlutterNapi() + } + + detachFromFlutterEngine() { + if (this.host.shouldDestroyEngineWithHost()) { + // The host owns the engine and should never have its engine taken by another exclusive + // activity. + throw new Error( + "The internal FlutterEngine created by " + + this.host + + " has been attached to by another activity. To persist a FlutterEngine beyond the " + + "ownership of this ablity, explicitly create a FlutterEngine"); + } + + // Default, but customizable, behavior is for the host to call {@link #onDetach} + // deterministically as to not mix more events during the lifecycle of the next exclusive + // activity. + this.host.detachFromFlutterEngine(); + } + + getAppComponent(): UIAbility { + const ability = this.host.getAbility(); + if (ability == null) { + throw new Error( + "FlutterActivityAndFragmentDelegate's getAppComponent should only " + + "be queried after onAttach, when the host's ability should always be non-null"); + } + return ability; + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.ensureAlive() + if (this.flutterEngine != null) { + Log.i(TAG, "Forwarding onNewWant() to FlutterEngine and sending pushRouteInformation message."); + this.flutterEngine.getAbilityControlSurface().onNewWant(want, launchParams); + const initialRoute = this.maybeGetInitialRouteFromIntent(want); + if (initialRoute && initialRoute.length > 0) { + this.flutterEngine.getNavigationChannel().pushRouteInformation(initialRoute); + } + } else { + Log.w(TAG, "onNewIntent() invoked before FlutterFragment was attached to an Activity."); + } + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); + this.ensureAlive(); + if (this.host.shouldRestoreAndSaveState()) { + wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] = this.flutterEngine.getRestorationChannel().getRestorationData(); + } + if (this.host.shouldAttachEngineToActivity()) { + const plugins:Record = {} + const result = this.flutterEngine.getAbilityControlSurface().onSaveState(reason, plugins); + wantParam[PLUGINS_RESTORATION_BUNDLE_KEY] = plugins; + return result + } + return AbilityConstant.OnSaveResult.ALL_REJECT + } + + addPlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().add(plugin) + } + + removePlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().remove(plugin.getUniqueClassName()) + } + + sendSettings(): void { + this.settings.sendSettings() + } +} + + +/** + * FlutterAbility句柄 + */ +interface Host extends FlutterEngineProvider, FlutterEngineConfigurator, PlatformPluginDelegate, MouseCursorViewDelegate { + + getAbility(): UIAbility; + + loadContent():void; + + shouldDispatchAppLifecycleState(): boolean; + + detachFromFlutterEngine(); + + shouldAttachEngineToActivity(): boolean; + + getCachedEngineId(): string; + + getCachedEngineGroupId(): string; + + /** + * Returns true if the {@link io.flutter.embedding.engine.FlutterEngine} used in this delegate + * should be destroyed when the host/delegate are destroyed. + */ + shouldDestroyEngineWithHost(): boolean; + + /** Returns the {@link FlutterShellArgs} that should be used when initializing Flutter. */ + getFlutterShellArgs(): FlutterShellArgs; + + /** Returns arguments that passed as a list of string to Dart's entrypoint function. */ + getDartEntrypointArgs(): Array; + + /** + * Returns the URI of the Dart library which contains the entrypoint method (example + * "package:foo_package/main.dart"). If null, this will default to the same library as the + * `main()` function in the Dart program. + */ + getDartEntrypointLibraryUri(): string; + + /** Returns the path to the app bundle where the Dart code exists. */ + getAppBundlePath(): string; + + /** + * Returns the Dart entrypoint that should run when a new {@link + * io.flutter.embedding.engine.FlutterEngine} is created. + */ + getDartEntrypointFunctionName(): string; + + /** Returns the initial route that Flutter renders. */ + getInitialRoute(): string; + + getWant(): Want; + + shouldRestoreAndSaveState(): boolean; +} + +export { Host, FlutterAbilityDelegate } \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets new file mode 100644 index 0000000000000000000000000000000000000000..996f455b9d045411425025f5c68089aee3f8938c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** The mode of the background of a Flutter {@code Activity}, either opaque or transparent. */ +enum BackgroundMode { + /** Indicates a FlutterActivity with an opaque background. This is the default. */ + opaque, + /** Indicates a FlutterActivity with a transparent background. */ + transparent +} + +export default class FlutterAbilityLaunchConfigs { + + static DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint"; + static DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri"; + static INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute"; + static SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; + static NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; + static HANDLE_DEEPLINKING_META_DATA_KEY = "flutter_deeplinking_enabled"; + // Intent extra arguments. + static EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; + static EXTRA_INITIAL_ROUTE = "route"; + static EXTRA_BACKGROUND_MODE = "background_mode"; + static EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; + static EXTRA_DART_ENTRYPOINT_ARGS = "dart_entrypoint_args"; + static EXTRA_CACHED_ENGINE_GROUP_ID = "cached_engine_group_id"; + static EXTRA_DESTROY_ENGINE_WITH_ACTIVITY = "destroy_engine_with_activity"; + static EXTRA_ENABLE_STATE_RESTORATION = "enable_state_restoration"; + + // Default configuration. + static DEFAULT_DART_ENTRYPOINT = "main"; + static DEFAULT_INITIAL_ROUTE = "/"; + static DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets new file mode 100644 index 0000000000000000000000000000000000000000..7953cad0836a9be4bf6bfd940594fdc787f45d66 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; + +export default interface FlutterEngineConfigurator { + + configureFlutterEngine(flutterEngine: FlutterEngine); + + cleanUpFlutterEngine(flutterEngine: FlutterEngine); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bdd7b6a809a77510f8942e81e0d91e7b4970893 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; +import common from '@ohos.app.ability.common'; + +export default interface FlutterEngineProvider { + provideFlutterEngine(context: common.Context): FlutterEngine; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..05695111937b486f3f498e9c87c12bdb85d829c5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { PlatformViewWrapper } from '../../plugin/platform/PlatformViewWrapper'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { DVModel, + DVModelChildren, + DVModelContainer, + DVModelEvents, + DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +/** + * 基础page组件,承载XComponent组件 + */ +@Component +export struct FlutterPage { + @State message: string = 'Hello World'; + + @State rootDvModel: DVModelContainer = RootDvModeManager.getRootDvMode(); + + build() { + DynamicView({ + model: this.rootDvModel.model as DVModel, + params: this.rootDvModel.model.params as DVModelParameters, + events: this.rootDvModel.model.events as DVModelEvents, + children: this.rootDvModel.model.children as DVModelChildren, + customBuilder: this.rootDvModel.model.builder as ($$: Record<"params",DVModelParameters >) => void + //customBuilder: this.rootDvModel.model.builder as ($$: { params: DVModelParameters }) => void + }) + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets new file mode 100644 index 0000000000000000000000000000000000000000..083b148b1b3677895fe467c8f3fd0365bbd07cc2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets @@ -0,0 +1,43 @@ +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; + +export default class OhosTouchProcessor { + private static POINTER_DATA_FIELD_COUNT: number = 35; + + static BYTES_PER_FIELD: number = 8; + + private static POINTER_DATA_FLAG_BATCHED: number = 1; + + public onTouchEvent(event: TouchEvent, transformMatrix: ESObject): void { + + } +} + +export enum PointerChange { + CANCEL = 0, + ADD = 1, + REMOVE = 2, + HOVER = 3, + DOWN = 4, + MOVE = 5, + UP = 6, + PAN_ZOOM_START = 7, + PAN_ZOOM_UPDATE = 8, + PAN_ZOOM_END = 9 +} + +export enum PointerDeviceKind { + TOUCH = 0, + MOUSE = 1, + STYLUS = 2, + INVERTED_STYLUS = 3, + TRACKPAD = 4, + UNKNOWN = 5 +} + +export enum PointerSignalKind { + NONE = 0, + SCROLL = 1, + SCROLL_INERTIA_CANCEL = 2, + SCALE = 3, + UNKNOWN = 4 +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets new file mode 100644 index 0000000000000000000000000000000000000000..a435d2a45cc960a5d6a4eb49c3d131c83b4d2dcb --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import SettingsChannel, { PlatformBrightness } from '../engine/systemchannels/SettingsChannel' +import I18n from '@ohos.i18n' + +export default class Settings { + settingsChannel: SettingsChannel; + + constructor(settingsChannel: SettingsChannel) { + this.settingsChannel = settingsChannel; + } + + sendSettings(): void { + this.settingsChannel.startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setTextScaleFactor(1.0) + .setNativeSpellCheckServiceDefined(false) + .setBrieflyShowPassword(false) + .setPlatformBrightness(PlatformBrightness.LIGHT) + .send(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d4306f92610e0cf610e87e76dc051151d40f9ec --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets @@ -0,0 +1,73 @@ +/** Tracks the motion events received by the FlutterView. */ +import PlainArray from '@ohos.util.PlainArray'; +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; +import Queue from '@ohos.util.Queue'; + +export class TouchEventTracker { + private eventById : PlainArray; + private unusedEvents : Queue; + private static INSTANCE:TouchEventTracker; + + public static getInstance(): TouchEventTracker { + if (TouchEventTracker.INSTANCE == null) { + TouchEventTracker.INSTANCE = new TouchEventTracker(); + } + return TouchEventTracker.INSTANCE; + } + + constructor() { + this.eventById = new PlainArray(); + this.unusedEvents = new Queue(); + } + + /** Tracks the event and returns a unique MotionEventId identifying the event. */ + public track(event :TouchEvent) : TouchEventId { + const eventId:TouchEventId = TouchEventId.createUnique(); + this.eventById.add(eventId.getId(), event); + this.unusedEvents.add(eventId.getId()); + return eventId; + } + + /** + * Returns the MotionEvent corresponding to the eventId while discarding all the motion events + * that occurred prior to the event represented by the eventId. Returns null if this event was + * popped or discarded. + */ + public pop(eventId : TouchEventId) : TouchEvent { + // remove all the older events. + while (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() < eventId.getId()) { + this.eventById.remove(this.unusedEvents.pop()); + } + + // remove the current event from the heap if it exists. + if (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() == eventId.getId()) { + this.unusedEvents.pop(); + } + + const event : TouchEvent = this.eventById.get(eventId.getId()); + this.eventById.remove(eventId.getId()); + return event; + } +} + +/** Represents a unique identifier corresponding to a motion event. */ +export class TouchEventId { + private static ID_COUNTER : number = 0; + private id : number; + + constructor(id : number) { + this.id = id; + } + + public static from(id : number) : TouchEventId { + return new TouchEventId(id); + } + + public static createUnique() : TouchEventId { + return new TouchEventId(TouchEventId.ID_COUNTER++); + } + + public getId() : number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd5b302da20485bea675770c746ad93dd71e848d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets @@ -0,0 +1,8 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class WindowInfoRepositoryCallbackAdapterWrapper { + + constructor() { + } + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..9910f14b6d71e2fc70e55eb8c7846ccbeffa0180 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import PlatformChannel, { + AppSwitcherDescription, + Brightness, + ClipboardContentFormat, + HapticFeedbackType, + PlatformMessageHandler, + SoundType, + SystemChromeStyle, + SystemUiMode, + SystemUiOverlay +} from '../embedding/engine/systemchannels/PlatformChannel'; +import pasteboard from '@ohos.pasteboard'; +import Log from '../util/Log'; +import vibrator from '@ohos.vibrator'; +import window from '@ohos.window'; +import common from '@ohos.app.ability.common'; + +/** + * ohos实现platform plugin + */ +export default class PlatformPlugin { + private static TAG = "PlatformPlugin"; + private callback = new PlatformPluginCallback(); + + constructor(platformChannel: PlatformChannel, context: common.Context, platformPluginDelegate?: PlatformPluginDelegate) { + this.callback.platformChannel = platformChannel; + this.callback.context = context; + this.callback.applicationContext = context.getApplicationContext(); + this.callback.platform = this; + + try { + window.getLastWindow(context, (err, data) => { + if (err.code) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + return; + } + this.callback.windowClass = data; + }); + } catch (err) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + } + this.callback.platformPluginDelegate = platformPluginDelegate; + this.callback.platformChannel.setPlatformMessageHandler(this.callback); + } + + + updateSystemUiOverlays(): void { + this.callback.windowClass.setWindowSystemBarEnable(this.callback.showBarOrNavigation); + if (this.callback.currentTheme != null) { + this.callback.setSystemChromeSystemUIOverlayStyle(this.callback.currentTheme); + } + } + + setUIAbilityContext(context: common.UIAbilityContext): void { + this.callback.uiAbilityContext = context; + } + + setSystemChromeChangeListener(): void { + if (this.callback.callbackId == null && this.callback.applicationContext != null) { + let that = this; + this.callback.callbackId = this.callback.applicationContext.on('environment', { + onConfigurationUpdated(config) { + Log.d(PlatformPlugin.TAG, "onConfigurationUpdated: " + that.callback.showBarOrNavigation); + that.callback.platformChannel.systemChromeChanged(that.callback.showBarOrNavigation.includes('status')); + }, + onMemoryLevel(level) { + } + }) + } + } +} + +export interface PlatformPluginDelegate { + popSystemNavigator(): boolean; +} + +class PlatformPluginCallback implements PlatformMessageHandler { + private static TAG = "PlatformPluginCallback"; + platform: PlatformPlugin; + windowClass: window.Window = null; + platformChannel: PlatformChannel; + platformPluginDelegate: PlatformPluginDelegate; + context: common.Context; + showBarOrNavigation: ('status' | 'navigation')[] = ['status', 'navigation']; + uiAbilityContext: common.UIAbilityContext = null; + callbackId: number = null; + applicationContext: common.ApplicationContext = null; + currentTheme: SystemChromeStyle = null; + + playSystemSound(soundType: SoundType) { + } + + vibrateHapticFeedback(feedbackType: HapticFeedbackType) { + switch (feedbackType) { + case HapticFeedbackType.STANDARD: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'touch' }); + break; + case HapticFeedbackType.LIGHT_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'notification' }).then(); + break; + case HapticFeedbackType.MEDIUM_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'ring' }); + break; + case HapticFeedbackType.HEAVY_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'alarm' }); + break; + case HapticFeedbackType.SELECTION_CLICK: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'physicalFeedback' }); + break; + } + } + + setPreferredOrientations(ohosOrientation: number) { + Log.d(PlatformPluginCallback.TAG, "ohosOrientation: " + ohosOrientation); + this.windowClass.setPreferredOrientation(ohosOrientation); + } + + setApplicationSwitcherDescription(description: AppSwitcherDescription) { + // representation described in the given {@code description}. + } + + showSystemOverlays(overlays: SystemUiOverlay[]) { + this.setSystemChromeEnabledSystemUIOverlays(overlays); + } + + showSystemUiMode(mode: SystemUiMode) { + this.setSystemChromeEnabledSystemUIMode(mode); + } + + setSystemUiChangeListener() { + this.platform.setSystemChromeChangeListener(); + } + + restoreSystemUiOverlays() { + this.platform.updateSystemUiOverlays(); + } + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle) { + Log.d(PlatformPluginCallback.TAG, "systemUiOverlayStyle:" + JSON.stringify(systemUiOverlayStyle)); + this.setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle); + } + + popSystemNavigator() { + if (this.platformPluginDelegate != null && this.platformPluginDelegate.popSystemNavigator()) { + return; + } + if (this.uiAbilityContext != null) { + this.uiAbilityContext.terminateSelf(); + } + } + + getClipboardData(format: ClipboardContentFormat): string { + // todo + return ""; + } + + setClipboardData(text: string) { + let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + let clipboard = pasteboard.getSystemPasteboard(); + clipboard.setData(pasteData); + } + + clipboardHasStrings(): boolean { + return false; + } + + setSystemChromeEnabledSystemUIMode(mode: SystemUiMode): void { + Log.d(PlatformPluginCallback.TAG, "mode: " + mode); + let uiConfig: ('status' | 'navigation')[] = []; + if (mode == SystemUiMode.LEAN_BACK) { + //全屏显示,通过点击显示器上的任何位置都可以显示状态和导航栏 + this.windowClass.setWindowLayoutFullScreen(false); + + } else if (mode == SystemUiMode.IMMERSIVE) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,应用程序不会接收到此手势 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.IMMERSIVE_STICKY) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,此手势由应用程序接收 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.EDGE_TO_EDGE) { + //全屏显示,在应用程序上呈现状态和导航元素 + this.windowClass.setWindowLayoutFullScreen(false); + uiConfig = ['status', 'navigation']; + + } else { + return; + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } + + setSystemChromeSystemUIOverlayStyle(systemChromeStyle: SystemChromeStyle): void { + let isStatusBarLightIconValue: boolean = false; + let statusBarColorValue: string = null; + let statusBarContentColorValue: string = null; + let navigationBarColorValue: string = null; + let isNavigationBarLightIconValue: boolean = false; + let navigationBarContentColorValue: string = null; + if (systemChromeStyle.statusBarIconBrightness != null) { + switch (systemChromeStyle.statusBarIconBrightness) { + case Brightness.DARK: + isStatusBarLightIconValue = false; + break; + case Brightness.LIGHT: + isStatusBarLightIconValue = true; + break; + } + } + + if (systemChromeStyle.statusBarColor != null) { + statusBarColorValue = "#" + systemChromeStyle.statusBarColor.toString(16); + } + + if (systemChromeStyle.systemStatusBarContrastEnforced != null) { + + } + + if (systemChromeStyle.systemNavigationBarIconBrightness != null) { + switch (systemChromeStyle.systemNavigationBarIconBrightness) { + case Brightness.DARK: + isNavigationBarLightIconValue = true; + break; + case Brightness.LIGHT: + isNavigationBarLightIconValue = false; + } + } + + if (systemChromeStyle.systemNavigationBarColor != null) { + navigationBarColorValue = "#" + systemChromeStyle.systemNavigationBarColor.toString(16); + } + + if (systemChromeStyle.systemNavigationBarContrastEnforced != null) { + + } + this.currentTheme = systemChromeStyle; + let systemBarProperties = new SystemBarProperties(); + systemBarProperties.statusBarColor = statusBarColorValue; + systemBarProperties.isStatusBarLightIcon = isStatusBarLightIconValue; + systemBarProperties.statusBarContentColor = statusBarContentColorValue; + systemBarProperties.navigationBarColor = navigationBarColorValue; + systemBarProperties.isNavigationBarLightIcon = isNavigationBarLightIconValue; + systemBarProperties.navigationBarContentColor = navigationBarContentColorValue; + Log.d(PlatformPluginCallback.TAG, "systemBarProperties: " + JSON.stringify(systemBarProperties)); + this.windowClass.setWindowSystemBarProperties(systemBarProperties); + } + + setSystemChromeEnabledSystemUIOverlays(overlays: SystemUiOverlay[]): void { + let uiConfig: ('status' | 'navigation')[] = []; + if (overlays.length == 0) { + + } + for (let index = 0; index < overlays.length; ++index) { + let overlayToShow = overlays[index]; + switch (overlayToShow) { + case SystemUiOverlay.TOP_OVERLAYS: + uiConfig.push('status'); //hide navigation + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + uiConfig.push('navigation'); //hide bar + break; + } + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } +} + +class SystemBarProperties { + statusBarColor?: string; + + isStatusBarLightIcon?: boolean; + + statusBarContentColor?: string; + + navigationBarColor?: string; + + isNavigationBarLightIcon?: boolean; + + navigationBarContentColor?: string; +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6e6f6bcfb5b863a2b5c65b9f398ec5e048f4ad6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler } from './BinaryMessenger'; +import Log from '../../util/Log'; +import { BinaryReply } from './BinaryMessenger'; +import { TaskQueue } from './BinaryMessenger'; +import MessageCodec from './MessageCodec'; +import { BinaryMessenger } from './BinaryMessenger'; +/** + * A named channel for communicating with the Flutter application using basic, asynchronous message + * passing. + * + *

Messages are encoded into binary before being sent, and binary messages received are decoded + * into Java objects. The {@link MessageCodec} used must be compatible with the one used by the + * Flutter application. This can be achieved by creating a BasicMessageChannel + * counterpart of this channel on the Dart side. The static Java type of messages sent and received + * is {@code Object}, but only values supported by the specified {@link MessageCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +export default class BasicMessageChannel { + public static TAG = "BasicMessageChannel#"; + public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; + private messenger: BinaryMessenger; + private name: string; + private codec: MessageCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MessageCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Sends the specified message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param message the message, possibly null. + * @param callback a {@link Reply} callback, possibly null. + */ + send(message: T, callback?: (reply: T)=>void): void { + this.messenger.send(this.name, this.codec.encodeMessage(message), callback == null ? null : new IncomingReplyHandler(callback, this.codec)); + } + + /** + * Registers a message handler on this channel for receiving messages sent from the Flutter + * application. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming message on this channel will be handled + * silently by sending a null reply. + * + * @param handler a {@link MessageHandler}, or null to deregister. + */ + setMessageHandler(handler: MessageHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler(this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + + +export interface Reply { + /** + * Handles the specified message reply. + * + * @param reply the reply, possibly null. + */ + reply: (reply: T) => void; +} + +export interface MessageHandler { + + /** + * Handles the specified message received from Flutter. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply + * handlers. The reply may be submitted asynchronously and invoked on any thread. + * + *

Any uncaught exception thrown by this method, or the preceding message decoding, will be + * caught by the channel implementation and logged, and a null reply message will be sent back + * to Flutter. + * + *

Any uncaught exception thrown during encoding a reply message submitted to the {@link + * Reply} is treated similarly: the exception is logged, and a null reply is sent to Flutter. + * + * @param message the message, possibly null. + * @param reply a {@link Reply} for sending a single message reply back to Flutter. + */ + onMessage(message: T, reply: Reply): void; +} + +class IncomingReplyHandler implements BinaryReply { + private callback: (reply: T)=>void; + private codec: MessageCodec + + constructor(callback:(reply: T)=>void, codec: MessageCodec) { + this.callback = callback + this.codec = codec + } + + reply(reply: ArrayBuffer) { + try { + this.callback(this.codec.decodeMessage(reply)); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message reply", e); + } + } +} + +class IncomingMessageHandler implements BinaryMessageHandler { + private handler: MessageHandler + private codec: MessageCodec + + constructor(handler: MessageHandler, codec: MessageCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, callback: BinaryReply) { + try { + this.handler.onMessage( + this.codec.decodeMessage(message), + { + reply: (reply: T): void => { + callback.reply(this.codec.encodeMessage(reply)); + } + }); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message", e); + callback.reply(null); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..578436417dc4a23cfaf2c5adbb9c8340efa5795d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using unencoded binary messages, represented as {@link ByteBuffer}s. + * + *

This codec is guaranteed to be compatible with the corresponding BinaryCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, messages are represented using {@code ByteData}. + */ + +export default class BinaryCodec implements MessageCodec { + private returnsDirectByteBufferFromDecoding: boolean = false; + static readonly INSTANCE_DIRECT = new BinaryCodec(true); + + constructor(returnsDirectByteBufferFromDecoding: boolean) { + this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; + } + + encodeMessage(message: ArrayBuffer): ArrayBuffer { + return message + } + + decodeMessage(message: ArrayBuffer): ArrayBuffer { + if (message == null) { + return message; + } else if (this.returnsDirectByteBufferFromDecoding) { + return message; + } else { + return message.slice(0, message.byteLength); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..988c6a57092f7913f20b65bf6afa97b310385931 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * An abstraction over the threading policy used to invoke message handlers. + * + *

These are generated by calling methods like {@link + * BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can be passed into platform + * channels' constructors to control the threading policy for handling platform channels' + * messages. + */ +export interface TaskQueue {} + +/** Options that control how a TaskQueue should operate and be created. */ +export class TaskQueueOptions { + private isSerial = true; + + getIsSerial() { + return this.isSerial; + } + + setIsSerial(isSerial: boolean): TaskQueueOptions { + this.isSerial = isSerial; + return this; + } +} + +/** + * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also + * used in the dual capacity to handle a reply received from Flutter after sending a message. + */ +export interface BinaryReply { + /** + * Handles the specified reply. + * + * @param reply the reply payload, a direct-allocated {@link ByteBuffer} or null. Senders of + * outgoing replies must place the reply bytes between position zero and current position. + * Reply receivers can read from the buffer directly. + */ + reply(reply: ArrayBuffer): void; +} + +/** Handler for incoming binary messages from Flutter. */ +export interface BinaryMessageHandler { + /** + * Handles the specified message. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter + * reply handlers. The reply may be submitted asynchronously. + * + *

Any uncaught exception thrown by this method will be caught by the messenger + * implementation and logged, and a null reply message will be sent back to Flutter. + * + * @param message the message {@link ByteBuffer} payload, possibly null. + * @param reply A {@link BinaryReply} used for submitting a reply back to Flutter. + */ + onMessage(message: ArrayBuffer, reply: BinaryReply): void; +} + +/** + * Facility for communicating with Flutter using asynchronous message passing with binary messages. + * The Flutter Dart code should use BinaryMessages to + * participate. + * + *

{@code BinaryMessenger} is expected to be utilized from a single thread throughout the + * duration of its existence. If created on the main thread, then all invocations should take place + * on the main thread. If created on a background thread, then all invocations should take place on + * that background thread. + * + * @see BasicMessageChannel , which supports message passing with Strings and semi-structured + * messages. + * @see MethodChannel , which supports communication using asynchronous method invocation. + * @see EventChannel , which supports communication using event streams. + */ +export interface BinaryMessenger { + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue; + + /** + * Sends a binary message to the Flutter application. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + */ + send(channel: String, message: ArrayBuffer): void; + + /** + * Sends a binary message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a {@link BinaryReply} callback invoked when the Flutter application responds to + * the message, possibly null. + */ + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void; + + /** + * Registers a handler to be invoked when the Flutter application sends a message to its host + * platform. + * + *

Registration overwrites any previous registration for the same channel name. Use a null + * handler to deregister. + * + *

If no handler has been registered for a particular channel, any incoming message on that + * channel will be handled silently by sending a null reply. + * + * @param channel the name {@link String} of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + * @param taskQueue a {@link BinaryMessenger.TaskQueue} that specifies what thread will execute + * the handler. Specifying null means execute on the platform thread. + */ + //setMessageHandler(channel: String, handler: BinaryMessageHandler) + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void; + // { + // if (taskQueue != null) { + // throw new Error("setMessageHandler called with nonnull taskQueue is not supported.") + // } + // } + + /** + * Enables the ability to queue messages received from Dart. + * + *

This is useful when there are pending channel handler registrations. For example, Dart may + * be initialized concurrently, and prior to the registration of the channel handlers. This + * implies that Dart may start sending messages while plugins are being registered. + */ + enableBufferingIncomingMessages(): void; + // { + // throw new Error("enableBufferingIncomingMessages not implemented."); + // } + + /** + * Disables the ability to queue messages received from Dart. + * + *

This can be used after all pending channel handlers have been registered. + */ + disableBufferingIncomingMessages(): void; + // { + // throw new Error("disableBufferingIncomingMessages not implemented."); + // } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..166659a32e819580f2d433886f763dc453d8a597 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + * A named channel for communicating with the Flutter application using asynchronous event streams. + * + *

Incoming requests for event stream setup are decoded from binary on receipt, and Java + * responses and events are encoded into binary before being transmitted back to Flutter. The {@link + * MethodCodec} used must be compatible with the one used by the Flutter application. This can be + * achieved by creating an EventChannel + * counterpart of this channel on the Dart side. The Java type of stream configuration arguments, + * events, and error details is {@code Object}, but only values supported by the specified {@link + * MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +import Log from '../../util/Log'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; + +const TAG = "EventChannel#"; + +export default class EventChannel { + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec?: MethodCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec ? codec : StandardMethodCodec.INSTANCE + this.taskQueue = taskQueue + } + + + /** + * Registers a stream handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming stream setup requests will be handled + * silently by providing an empty stream. + * + * @param handler a {@link StreamHandler}, or null to deregister. + */ + setStreamHandler(handler: StreamHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger)); + } + } +} + +/** + * Handler of stream setup and teardown requests. + * + *

Implementations must be prepared to accept sequences of alternating calls to {@link + * #onListen(Object, EventChannel.EventSink)} and {@link #onCancel(Object)}. Implementations + * should ideally consume no resources when the last such call is not {@code onListen}. In typical + * situations, this means that the implementation should register itself with platform-specific + * event sources {@code onListen} and deregister again {@code onCancel}. + */ +export interface StreamHandler { + /** + * Handles a request to set up an event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + * @param arguments stream configuration arguments, possibly null. + * @param events an {@link EventSink} for emitting events to the Flutter receiver. + */ + onListen(args: ESObject, events: EventSink): void; + + /** + * Handles a request to tear down the most recently created event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + *

The channel implementation may call this method with null arguments to separate a pair of + * two consecutive set up requests. Such request pairs may occur during Flutter hot restart. Any + * uncaught exception thrown in this situation will be logged without notifying Flutter. + * + * @param arguments stream configuration arguments, possibly null. + */ + onCancel(args: ESObject): void; +} + +/** + * Event callback. Supports dual use: Producers of events to be sent to Flutter act as clients of + * this interface for sending events. Consumers of events sent from Flutter implement this + * interface for handling received events (the latter facility has not been implemented yet). + */ +export interface EventSink { + /** + * Consumes a successful event. + * + * @param event the event, possibly null. + */ + success(event: ESObject): void; + + /** + * Consumes an error event. + * + * @param errorCode an error code String. + * @param errorMessage a human-readable error message String, possibly null. + * @param errorDetails error details, possibly null + */ + error(errorCode: string, errorMessage: string, errorDetails: ESObject): void; + + /** + * Consumes end of stream. Ensuing calls to {@link #success(Object)} or {@link #error(String, + * String, Object)}, if any, are ignored. + */ + endOfStream(): void; +} + +class IncomingStreamRequestHandler implements BinaryMessageHandler { + private handler: StreamHandler; + private activeSink = new AtomicReference(null); + private codec: MethodCodec; + private name: string; + private messenger: BinaryMessenger; + + constructor(handler: StreamHandler, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.handler = handler; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + if (call.method == "listen") { + this.onListen(call.args, reply); + } else if (call.method == "cancel") { + this.onCancel(call.args, reply); + } else { + reply.reply(null); + } + } + + onListen(args: ESObject, callback: BinaryReply): void { + const eventSink = new EventSinkImplementation(this.activeSink, this.name, this.codec, this.messenger); + const oldSink = this.activeSink.getAndSet(eventSink); + if (oldSink != null) { + // Repeated calls to onListen may happen during hot restart. + // We separate them with a call to onCancel. + try { + this.handler.onCancel(null); + } catch (e) { + Log.e(TAG + this.name, "Failed to close existing event stream", e); + } + } + try { + this.handler.onListen(args, eventSink); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + this.activeSink.set(null); + Log.e(TAG + this.name, "Failed to open event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } + + onCancel(args: ESObject, callback: BinaryReply): void { + const oldSink = this.activeSink.getAndSet(null); + if (oldSink != null) { + try { + this.handler.onCancel(args); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + Log.e(TAG + this.name, "Failed to close event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } else { + callback.reply(this.codec.encodeErrorEnvelope("error", "No active stream to cancel", null)); + } + } +} + +class EventSinkImplementation implements EventSink { + private hasEnded = false; + private activeSink: AtomicReference; + private messenger: BinaryMessenger; + private codec: MethodCodec; + private name: string; + + constructor(activeSink: AtomicReference, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.activeSink = activeSink; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + success(event: ESObject): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send(this.name, this.codec.encodeSuccessEnvelope(event)); + } + + error(errorCode: string, errorMessage: string, errorDetails: ESObject) { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send( + this.name, this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + } + + endOfStream(): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.hasEnded = true; + this.messenger.send(this.name, null); + } +} + +class AtomicReference { + private value: T; + + constructor(value: T) { + this.value = value + } + + get(): T { + return this.value; + } + + set(newValue: T): void { + this.value = newValue; + } + + getAndSet(newValue: T) { + const oldValue = this.value; + this.value = newValue; + return oldValue; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets new file mode 100644 index 0000000000000000000000000000000000000000..03af6b520acc908d9cb63914ca2236736218aa77 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterException implements Error { + stack?: string; + message: string; + name: string; + code: string; + details: ESObject + + constructor(code: string, message: string, details: ESObject) { + this.message = message; + this.code = code; + this.details =details; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c289c6054e952a5cf7ed48b58fcfab6e343533b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; +import MethodCodec from './MethodCodec'; +import StringCodec from './StringCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, JSON messages are handled by the JSON facilities of the dart:convert package. + */ +export default class JSONMessageCodec implements MessageCodec { + static INSTANCE = new JSONMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + return StringCodec.INSTANCE.encodeMessage(JSON.stringify(message)); + } + + decodeMessage(message: ArrayBuffer): ESObject { + if (message == null) { + return null; + } + try { + const jsonStr = StringCodec.INSTANCE.decodeMessage(message); + return JSON.parse(jsonStr); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b5bf1d0891fe841d7380e0e6166ca5b82793e7b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import Log from '../../util/Log'; + +import ToolUtils from '../../util/ToolUtils'; +import FlutterException from './FlutterException'; +import JSONMessageCodec from './JSONMessageCodec'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as methods arguments and result payloads are those supported by {@link + * JSONMessageCodec}. + */ +export default class JSONMethodCodec implements MethodCodec { + static INSTANCE = new JSONMethodCodec(); + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + try { + const map: Record = { + "method": methodCall.method, "args": methodCall.args + } + + return JSONMessageCodec.INSTANCE.encodeMessage(map); + } catch (e) { + throw new Error("Invalid JSON"); + } + } + + decodeMethodCall(message: ArrayBuffer): MethodCall { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(message); + if (ToolUtils.isObj(json)) { + const method: string = json["method"]; + const args: ESObject = json["args"]; + if (typeof method == 'string') { + return new MethodCall(method, args); + } + } + throw new Error("Invalid method call: " + json); + } catch (e) { + throw new Error("Invalid JSON:" + JSON.stringify(e)); + } + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([result]); + } + + encodeErrorEnvelope(errorCode: ESObject, errorMessage: string, errorDetails: ESObject) { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(envelope); + if (json instanceof Array) { + if (json.length == 1) { + return json[0]; + } + if (json.length == 3) { + const code: string = json[0]; + const message: string = json[1]; + const details: ESObject = json[2]; + if (typeof code == 'string' && (message == null || typeof message == 'string')) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Invalid envelope: " + json); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..663d57af19c70523e44a5f48cc61e22ab0dc5b33 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * A message encoding/decoding mechanism. + */ +export default interface MessageCodec { + /** + * Encodes the specified message into binary. + */ + encodeMessage(message: T) : ArrayBuffer; + + /** + * Decodes the specified message from binary. + * + */ + decodeMessage(message: ArrayBuffer): T; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets new file mode 100644 index 0000000000000000000000000000000000000000..0042c25c3b21f484cda8158e5485bb57e73dfd82 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import ToolUtils from '../../util/ToolUtils'; +/** Command object representing a method call on a {@link MethodChannel}. */ +export default class MethodCall { + /** The name of the called method. */ + method: string; + + /** + * Arguments for the call. + * + *

Consider using {@link #arguments()} for cases where a particular run-time type is expected. + * Consider using {@link #argument(String)} when that run-time type is {@link Map} or {@link + * JSONObject}. + */ + args: ESObject; + + constructor(method: string, args: ESObject) { + this.method = method + this.args = args + } + + argument(key: string): ESObject { + if (this.args == null) { + return null; + } else if (this.args instanceof Map) { + return (this.args as Map).get(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args[key] + } else { + throw new Error("ClassCastException"); + } + } + + hasArgument(key: string): boolean { + if (arguments == null) { + return false; + } else if (arguments instanceof Map) { + return (this.args as Map).has(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args.hasOwnProperty(key); + } else { + throw new Error("ClassCastException"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..e491ed5f7fec63ad1064c7e7ddbe468aaf3821df --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; +/** + * A named channel for communicating with the Flutter application using asynchronous method calls. + * + *

Incoming method calls are decoded from binary on receipt, and Java results are encoded into + * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible + * with the one used by the Flutter application. This can be achieved by creating a MethodChannel + * counterpart of this channel on the Dart side. The Java type of method call arguments and results + * is {@code Object}, but only values supported by the specified {@link MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ + +export default class MethodChannel { + static TAG = "MethodChannel#"; + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MethodCodec = StandardMethodCodec.INSTANCE, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Invokes a method on this channel, optionally expecting a result. + * + *

Any uncaught exception thrown by the result callback will be caught and logged. + * + * @param method the name String of the method. + * @param arguments the arguments for the invocation, possibly null. + * @param callback a {@link Result} callback for the invocation result, or null. + */ + invokeMethod(method: string, args: ESObject, callback?: MethodResult): void { + this.messenger.send(this.name, this.codec.encodeMethodCall(new MethodCall(method, args)), callback == null ? null : new IncomingResultHandler(callback, this.codec)); + } + + /** + * Registers a method call handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming method call on this channel will be handled + * silently by sending a null reply. This results in a MissingPluginException + * on the Dart side, unless an OptionalMethodChannel + * is used. + * + * @param handler a {@link MethodCallHandler}, or null to deregister. + */ + setMethodCallHandler(handler: MethodCallHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + +/** A handler of incoming method calls. */ +export interface MethodCallHandler { + /** + * Handles the specified method call received from Flutter. + * + *

Handler implementations must submit a result for all incoming calls, by making a single + * call on the given {@link Result} callback. Failure to do so will result in lingering Flutter + * result handlers. The result may be submitted asynchronously and on any thread. Calls to + * unknown or unimplemented methods should be handled using {@link Result#notImplemented()}. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged, and an error result will be sent back to Flutter. + * + *

The handler is called on the platform thread (Android main thread) by default, or + * otherwise on the thread specified by the {@link BinaryMessenger.TaskQueue} provided to the + * associated {@link MethodChannel} when it was created. See also Threading in + * the Flutter Engine. + * + * @param call A {@link MethodCall}. + * @param result A {@link Result} used for submitting the result of the call. + */ + onMethodCall(call: MethodCall, result: MethodResult): void; +} + +/** + * Method call result callback. Supports dual use: Implementations of methods to be invoked by + * Flutter act as clients of this interface for sending results back to Flutter. Invokers of + * Flutter methods provide implementations of this interface for handling results received from + * Flutter. + * + *

All methods of this class can be invoked on any thread. + */ +export interface MethodResult { + /** + * Handles a successful result. + * + * @param result The result, possibly null. The result must be an Object type supported by the + * codec. For instance, if you are using {@link StandardMessageCodec} (default), please see + * its documentation on what types are supported. + */ + success: (result: ESObject) => void; + + /** + * Handles an error result. + * + * @param errorCode An error code String. + * @param errorMessage A human-readable error message String, possibly null. + * @param errorDetails Error details, possibly null. The details must be an Object type + * supported by the codec. For instance, if you are using {@link StandardMessageCodec} + * (default), please see its documentation on what types are supported. + */ + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) => void; + + /** Handles a call to an unimplemented method. */ + notImplemented: () => void; +} + +class IncomingResultHandler implements BinaryReply { + private callback: MethodResult; + private codec: MethodCodec; + + constructor(callback: MethodResult, codec: MethodCodec) { + this.callback = callback; + this.codec = codec + } + + reply(reply: ArrayBuffer): void { + try { + if (reply == null) { + this.callback.notImplemented(); + } else { + try { + this.callback.success(this.codec.decodeEnvelope(reply)); + } catch (e) { + this.callback.error(e.code, e.getMessage(), e.details); + } + } + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call result", e); + } + } +} + +class IncomingMethodCallHandler implements BinaryMessageHandler { + private handler: MethodCallHandler; + private codec: MethodCodec; + + constructor(handler: MethodCallHandler, codec: MethodCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + try { + this.handler.onMethodCall( + call, { + success: (result: ESObject): void => { + reply.reply(this.codec.encodeSuccessEnvelope(result)); + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject): void => { + reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + }, + + notImplemented: (): void => { + Log.w(MethodChannel.TAG,"method not implemented"); + reply.reply(null); + } + }); + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call", e); + reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..86ed92aca6d512fa8247d963619acf67f29b7fe4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from './MethodCall'; +/** + * A codec for method calls and enveloped results. + * + *

Method calls are encoded as binary messages with enough structure that the codec can extract a + * method name String and an arguments Object. These data items are used to populate a {@link + * MethodCall}. + * + *

All operations throw {@link IllegalArgumentException}, if conversion fails. + */ +export default interface MethodCodec { + /** + * Encodes a message call into binary. + * + * @param methodCall a {@link MethodCall}. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeMethodCall(methodCall: MethodCall): ArrayBuffer; + + /** + * Decodes a message call from binary. + * + * @param methodCall the binary encoding of the method call as a {@link ByteBuffer}. + * @return a {@link MethodCall} representation of the bytes between the given buffer's current + * position and its limit. + */ + decodeMethodCall(methodCall: ArrayBuffer): MethodCall; + + /** + * Encodes a successful result into a binary envelope message. + * + * @param result The result value, possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeSuccessEnvelope(result: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message with the native stacktrace. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @param errorStacktrace Platform stacktrace for the error. possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer + + /** + * Decodes a result envelope from binary. + * + * @param envelope the binary encoding of a result envelope as a {@link ByteBuffer}. + * @return the enveloped result Object. + * @throws FlutterException if the envelope was an error envelope. + */ + decodeEnvelope(envelope: ArrayBuffer): ESObject +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb92c8eb1acc0406e2f14229e8d29d0ef19b3030 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets @@ -0,0 +1,14 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..3de7603e1f576a9af23be11b9f185c67730429b3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets @@ -0,0 +1,310 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * MessageCodec using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMessageCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Supported messages are acyclic values of these forms: + * + *

    + *
  • null + *
  • Booleans + *
  • number + *
  • BigIntegers (see below) + *
  • Int8Array, Int32Array, Float32Array, Float64Array + *
  • Strings + *
  • Array[] + *
  • Lists of supported values + *
  • Maps with supported keys and values + *
+ * + *

On the Dart side, these values are represented as follows: + * + *

    + *
  • null: null + *
  • Boolean: bool + *
  • Byte, Short, Integer, Long: int + *
  • Float, Double: double + *
  • String: String + *
  • byte[]: Uint8List + *
  • int[]: Int32List + *
  • long[]: Int64List + *
  • float[]: Float32List + *
  • double[]: Float64List + *
  • List: List + *
  • Map: Map + *
+ * + *

BigIntegers are represented in Dart as strings with the hexadecimal representation of the + * integer's value. + * + *

To extend the codec, overwrite the writeValue and readValueOfType methods. + */ +export default class StandardMessageCodec implements MessageCodec { + private static TAG = "StandardMessageCodec#"; + static INSTANCE = new StandardMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + const stream = ByteBuffer.from(new ArrayBuffer(1024)) + this.writeValue(stream, message); + return stream.buffer + } + + decodeMessage(message: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(message) + return this.readValue(buffer) + } + + private static NULL = 0; + private static TRUE = 1; + private static FALSE = 2; + private static INT32 = 3; + private static INT64 = 4; + private static BIGINT = 5; + private static FLOAT64 = 6; + private static STRING = 7; + private static UINT8_ARRAY = 8; + private static INT32_ARRAY = 9; + private static INT64_ARRAY = 10; + private static FLOAT64_ARRAY = 11; + private static LIST = 12; + private static MAP = 13; + private static FLOAT32_ARRAY = 14; + + + writeValue(stream: ByteBuffer, value: ESObject): ESObject { + if (value == null || value == undefined) { + stream.writeInt8(StandardMessageCodec.NULL) + } else if (typeof value === "boolean") { + stream.writeInt8(value ? StandardMessageCodec.TRUE : StandardMessageCodec.FALSE) + } else if (typeof value === "number") { + if (Number.isInteger(value)) { //整型 + if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { + stream.writeInt8(StandardMessageCodec.INT32) + stream.writeInt32(value, true) + } else { + stream.writeInt8(StandardMessageCodec.INT64) + stream.writeInt64(value, true) + } + } else { //浮点型 + stream.writeInt8(StandardMessageCodec.FLOAT64) + this.writeAlignment(stream, 8); + stream.writeFloat64(value, true) + } + } else if (typeof value === "string") { + stream.writeInt8(StandardMessageCodec.STRING) + let stringBuff = StringUtils.stringToArrayBuffer(value) + this.writeBytes(stream, new Uint8Array(stringBuff)) + } else if (value instanceof Uint8Array) { + stream.writeInt8(StandardMessageCodec.UINT8_ARRAY) + this.writeBytes(stream, value) + } else if (value instanceof Int32Array) { + stream.writeInt8(StandardMessageCodec.INT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeInt32(item, true)) + } else if (value instanceof Float32Array) { + stream.writeInt8(StandardMessageCodec.FLOAT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeFloat32(item, true)) + } else if (value instanceof Float64Array) { + stream.writeInt8(StandardMessageCodec.FLOAT64_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 8); + value.forEach(item => stream.writeFloat64(item, true)) + } else if (value instanceof Array) { + stream.writeInt8(StandardMessageCodec.LIST) + this.writeSize(stream, value.length); + value.forEach((item: ESObject): void => this.writeValue(stream, item)) + } else if (value instanceof Map) { + stream.writeInt8(StandardMessageCodec.MAP) + this.writeSize(stream, value.size); + value.forEach((value: ESObject, key: ESObject) => { + this.writeValue(stream, key); + this.writeValue(stream, value); + }) + } else if (typeof value == 'object') { + this.writeValue(stream, new Map(value.entries())) + } + return stream + } + + writeAlignment(stream: ByteBuffer, alignment: number) { + let mod: number = stream.byteOffset % alignment; + if (mod != 0) { + for (let i = 0; i < alignment - mod; i++) { + stream.writeInt8(0); + } + } + } + + writeSize(stream: ByteBuffer, value: number) { + if (value < 254) { + stream.writeInt8(value); + } else if (value <= 0xffff) { + stream.writeInt8(254); + stream.writeInt16(value, true); + } else { + stream.writeInt8(255); + stream.writeInt32(value, true); + } + } + + writeBytes(stream: ByteBuffer, bytes: Uint8Array) { + this.writeSize(stream, bytes.length) + bytes.forEach(item => stream.writeInt8(item)) + } + + readSize(buffer: ByteBuffer) { + let value = buffer.readInt8() & 0xff; + if (value < 254) { + return value; + } else if (value == 254) { + return buffer.readInt16(true); + } else { + return buffer.readInt32(true); + } + } + + readAlignment(buffer: ByteBuffer, alignment: number) { + let mod = buffer.byteOffset % alignment; + if (mod != 0) { + buffer.skip(alignment - mod); + } + } + + readValue(buffer: ByteBuffer): ESObject { + let type = buffer.readInt8() + return this.readValueOfType(type, buffer); + } + + readBytes(buffer: ByteBuffer): Uint8Array { + let length = this.readSize(buffer); + let bytes = new Uint8Array(length) + for (let i = 0; i < length; i++) { + bytes[i] = buffer.readUint8() + } + return bytes; + } + + readValueOfType(type: number, buffer: ByteBuffer): ESObject { + let result: ESObject; + switch (type) { + case StandardMessageCodec.NULL: + result = null; + break; + case StandardMessageCodec.TRUE: + result = true; + break; + case StandardMessageCodec.FALSE: + result = false; + break; + case StandardMessageCodec.INT32: + result = buffer.readInt32(true); + break; + case StandardMessageCodec.INT64: + result = buffer.readInt64(true); + break; + case StandardMessageCodec.BIGINT: + result = buffer.readBigInt64(true) + case StandardMessageCodec.FLOAT64: + this.readAlignment(buffer, 8); + result = buffer.readFloat64(true) + break; + case StandardMessageCodec.STRING: { + let bytes = this.readBytes(buffer); + result = StringUtils.arrayBufferToString(bytes.buffer); + break; + } + case StandardMessageCodec.UINT8_ARRAY: { + result = this.readBytes(buffer); + break; + } + case StandardMessageCodec.INT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Int32Array(length) + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt32(true) + } + result = array; + break; + } + case StandardMessageCodec.INT64_ARRAY: { //这里是都城array 还是 bigint待定 + let length = this.readSize(buffer); + let array: Array = new Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt64(true) + } + result = array; + break; + } + case StandardMessageCodec.FLOAT64_ARRAY: { + let length = this.readSize(buffer); + let array = new Float64Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat64(true) + } + result = array; + break; + } + case StandardMessageCodec.LIST: { + let length = this.readSize(buffer); + let array: Array = new Array(length) + for (let i = 0; i < length; i++) { + array[i] = this.readValue(buffer) + } + result = array; + break; + } + case StandardMessageCodec.MAP: { + let size = this.readSize(buffer); + let map: Map = new Map() + for (let i = 0; i < size; i++) { + map.set(this.readValue(buffer), this.readValue(buffer)); + } + result = map; + break; + } + case StandardMessageCodec.FLOAT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Float32Array(length); + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat32(true) + } + result = array; + break; + } + default: + throw new Error("Message corrupted"); + } + return result; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4417c54eb56d55355b73104ee8626a17836735f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import FlutterException from './FlutterException'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMessageCodec from './StandardMessageCodec'; + +/** + * A {@link MethodCodec} using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMethodCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as method arguments and result payloads are those supported by {@link + * StandardMessageCodec}. + */ +export default class StandardMethodCodec implements MethodCodec { + private static TAG = "StandardMethodCodec"; + public static INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE); + + private messageCodec: StandardMessageCodec; + + /** Creates a new method codec based on the specified message codec. */ + constructor(messageCodec: StandardMessageCodec) { + this.messageCodec = messageCodec; + } + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + this.messageCodec.writeValue(stream, methodCall.method); + this.messageCodec.writeValue(stream, methodCall.args); + return stream.buffer; + } + + decodeMethodCall(methodCall: ArrayBuffer): MethodCall { + const buffer = ByteBuffer.from(methodCall); + const method: ESObject = this.messageCodec.readValue(buffer); + const args: ESObject = this.messageCodec.readValue(buffer); + if (typeof method == 'string' && !buffer.hasRemaining()) { + return new MethodCall(method, args); + } + throw new Error("Method call corrupted"); + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(0); + this.messageCodec.writeValue(stream, result); + return stream.buffer; + } + + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + return stream.buffer; + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + this.messageCodec.writeValue(stream, errorStacktrace); + return stream.buffer; + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(envelope); + const flag = buffer.readInt8(); + switch (flag) { + case 0: { + const result: ESObject = this.messageCodec.readValue(buffer); + if (!buffer.hasRemaining()) { + return result; + } + // Falls through intentionally. + } + case 1: { + const code: ESObject = this.messageCodec.readValue(buffer); + const message: ESObject = this.messageCodec.readValue(buffer); + const details: ESObject = this.messageCodec.readValue(buffer); + if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Envelope corrupted"); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..e43be76b5527f6180d9b30ede5c1c07dff84c729 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using UTF-8 encoded String messages. + * + *

This codec is guaranteed to be compatible with the corresponding StringCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + */ +export default class StringCodec implements MessageCodec { + static readonly INSTANCE = new StringCodec(); + + encodeMessage(message: string): ArrayBuffer { + if (message == null) { + return null; + } + return StringUtils.stringToArrayBuffer(message); + } + + decodeMessage(message: ArrayBuffer): string { + if (message == null) { + return null; + } + return StringUtils.arrayBufferToString(message); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets new file mode 100644 index 0000000000000000000000000000000000000000..72735c0a29a1e893e8bf986458cea0da82df0d2b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TextEditState } from '../../embedding/engine/systemchannels/TextInputChannel'; +import Log from '../../util/Log'; +import inputMethod from '@ohos.inputMethod'; +import ArrayList from '@ohos.util.ArrayList'; +import { TextEditingDelta } from './TextEditingDelta'; + +const TAG = "ListenableEditingState"; +export class ListenableEditingState { + //Cache used to storage software keyboard input action + private mStringCache: string; + private mSelectionStartCache: number; + private mSelectionEndCache: number; + private mComposingStartCache: number; + private mComposingEndCache: number; + //used to compare with Cache + private mTextInputState: TextEditState; + private mListeners: ArrayList = new ArrayList(); + private mPendingListeners: ArrayList = new ArrayList(); + private mBatchTextEditingDeltas: ArrayList = new ArrayList(); + private mChangeNotificationDepth: number; + private mBatchEditNestDepth: number; + + private mTextWhenBeginBatchEdit: string; + private mSelectionStartWhenBeginBatchEdit: number; + private mSelectionEndWhenBeginBatchEdit: number; + private mComposingStartWhenBeginBatchEdit: number; + private mComposingEndWhenBeginBatchEdit: number; + + + constructor() { + this.mStringCache = ""; + this.mSelectionStartCache = 0; + this.mSelectionEndCache = 0; + this.mComposingStartCache = -1; + this.mComposingEndCache = -1; + } + + + getSelectionStart(): number { + return this.mSelectionStartCache; + } + + getSelectionEnd(): number { + return this.mSelectionEndCache; + } + + getComposingStart(): number { + return this.mComposingStartCache; + } + + getComposingEnd(): number { + return this.mComposingEndCache; + } + + getStringCache(): string { + return this.mStringCache; + } + + setSelectionStart(newSelectionStart: number): void { + this.mSelectionStartCache = newSelectionStart; + } + + setSelectionEnd(newSelectionEnd: number): void { + this.mSelectionEndCache = newSelectionEnd; + } + + setComposingStart(newComposingStart: number): void { + this.mComposingStartCache = newComposingStart; + } + + setComposingEnd(newComposingEnd: number): void { + this.mComposingEndCache = newComposingEnd; + } + + setStringCache(newStringCache: string): void { + this.mStringCache = newStringCache; + } + + notifyListener(listener: EditingStateWatcher, + textChanged: boolean, + selectionChanged: boolean, + composingChanged: boolean): void { + this.mChangeNotificationDepth++; + listener.didChangeEditingState(textChanged, selectionChanged, composingChanged); + this.mChangeNotificationDepth--; + } + + notifyListenersIfNeeded(textChanged: boolean, selectionChanged: boolean, composingChanged: boolean) { + if (textChanged || selectionChanged || composingChanged) { + for(const listener of this.mListeners) { + this.notifyListener(listener, textChanged, selectionChanged, composingChanged); + } + + } + } + + handleInsertTextEvent(text: string): void { + if(this.mTextInputState == null) { + Log.e(TAG, "mTextInputState is null"); + } + if(this.mStringCache.length == this.mSelectionStartCache) { + //Insert text one by one + this.mStringCache += text; + this.setSelectionStart(this.mStringCache.length); + this.setSelectionEnd(this.mStringCache.length); + + } else if(this.mStringCache.length > this.mSelectionStartCache) { + //Insert text in the middle of string + let tempStr: string = this.mStringCache.substring(0, this.mSelectionStartCache) + text + this.mStringCache.substring(this.mSelectionStartCache); + this.mStringCache = tempStr; + this.mSelectionStartCache += text.length; + this.mSelectionEndCache = this.mSelectionStartCache; + } + if(this.mListeners == null) { + Log.e(TAG, "mListeners is null"); + return; + } + this.notifyListenersIfNeeded(true, true, false); + } + + updateTextInputState(state: TextEditState): void { + this.beginBatchEdit(); + this.setStringCache(state.text); + if(state.hasSelection()) { + this.setSelectionStart(state.selectionStart); + this.setSelectionEnd(state.selectionEnd); + } else { + this.setSelectionStart(0); + this.setSelectionEnd(0); + } + this.endBatchEdit(); + } + + beginBatchEdit(): void { + this.mBatchEditNestDepth++; + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "editing state should not be changed in a listener callback"); + } + if(this.mBatchEditNestDepth == 1 && !this.mListeners.isEmpty()) { + this.mTextWhenBeginBatchEdit = this.getStringCache(); + this.mSelectionStartWhenBeginBatchEdit = this.getSelectionStart(); + this.mSelectionEndWhenBeginBatchEdit = this.getSelectionEnd(); + this.mComposingStartWhenBeginBatchEdit = this.getComposingStart(); + this.mComposingEndWhenBeginBatchEdit = this.getComposingEnd(); + } + } + + endBatchEdit(): void { + if (this.mBatchEditNestDepth == 0) { + Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit"); + return; + } + if(this.mBatchEditNestDepth == 1) { + Log.d(TAG,"mBatchEditNestDepth == 1"); + for(const listener of this.mPendingListeners) { + this.notifyListener(listener, true, true, true); + } + + if(!this.mListeners.isEmpty()) { + Log.d(TAG, "didFinishBatchEdit with " + this.mListeners.length + " listener(s)"); + const textChanged = !(this.mStringCache == this.mTextWhenBeginBatchEdit); + const selectionChanged = this.mSelectionStartWhenBeginBatchEdit != this.getSelectionStart() + || this.mSelectionEndWhenBeginBatchEdit != this.getSelectionEnd(); + const composingRegionChanged = this.mComposingStartWhenBeginBatchEdit != this.getComposingStart() + || this.mComposingEndWhenBeginBatchEdit != this.getComposingEnd(); + Log.d(TAG,"textChanged: " + textChanged + " selectionChanged: " + selectionChanged + + " composingRegionChanged: " + composingRegionChanged); + this.notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged); + } + } + for(const listener of this.mPendingListeners) { + this.mListeners.add(listener); + } + this.mPendingListeners.clear(); + this.mBatchEditNestDepth--; + + } + + addEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "adding a listener " + JSON.stringify(listener) + " in a listener callback"); + } + if(this.mBatchEditNestDepth > 0) { + Log.d(TAG, "a listener was added to EditingState while a batch edit was in progress"); + this.mPendingListeners.add(listener); + } else { + this.mListeners.add(listener); + } + } + + removeEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "removing a listener " + JSON.stringify(listener) + " in a listener callback"); + } + this.mListeners.remove(listener); + if(this.mBatchEditNestDepth > 0) { + this.mPendingListeners.remove(listener); + } + } + + handleDeleteEvent(leftOrRight: boolean, length: number): void { + if(leftOrRight == false) { + //delete left + if(this.mSelectionStartCache == 0) { + return; + } + this.mSelectionStartCache -= length; + let tempStr: string = this.mStringCache.slice(0, this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionStartCache + length); + this.mStringCache = tempStr; + this.mSelectionEndCache = this.mSelectionStartCache; + } else if(leftOrRight == true) { + //delete right + if(this.mSelectionStartCache == this.mStringCache.length) { + return; + } + this.mSelectionEndCache += length; + let tempStr: string = this.mStringCache.slice(0,this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionEndCache); + this.mStringCache = tempStr; + this.mSelectionStartCache = this.mSelectionEndCache; + } + this.notifyListenersIfNeeded(true, true, false); + } + + handleFunctionKey(functionKey: inputMethod.FunctionKey): void { + switch (functionKey.enterKeyType) { + case inputMethod.EnterKeyType.PREVIOUS: + case inputMethod.EnterKeyType.UNSPECIFIED: + case inputMethod.EnterKeyType.NONE: + case inputMethod.EnterKeyType.GO: + case inputMethod.EnterKeyType.SEARCH: + case inputMethod.EnterKeyType.SEND: + case inputMethod.EnterKeyType.NEXT: + case inputMethod.EnterKeyType.DONE: + + } + } + + handleSelectByRange(range: inputMethod.Range): void { + Log.d(TAG, "handleSelectByRange start: " + range.start +" end: " + range.end); + } + + + +} + +export interface EditingStateWatcher { + // Changing the editing state in a didChangeEditingState callback may cause unexpected + // behavior. + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets new file mode 100644 index 0000000000000000000000000000000000000000..c61296f6dae8b30fcb035f72d8457ca36d83a015 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; + +export class TextEditingDelta { + private static TAG = "TextEditingDelta"; + private oldText: string; + private deltaText: string; + private deltaStart: number; + private deltaEnd: number; + private newSelectionStart: number; + private newSelectionEnd: number; + private newComposingStart: number; + private newComposingEnd: number; + + constructor(oldEditable: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number, + replacementDestinationStart?: number, + replacementDestinationEnd?: number, + replacementSource?: string,) { + this.newSelectionStart = selectionStart; + this.newSelectionEnd = selectionEnd; + this.newComposingStart = composingStart; + this.newComposingEnd = composingEnd; + if(replacementDestinationStart === undefined || + replacementDestinationEnd === undefined || + replacementSource === undefined) { + this.setDeltas(oldEditable, "", -1, -1); + } else { + this.setDeltas( + oldEditable, + replacementSource, + replacementDestinationStart, + replacementDestinationEnd); + } + + } + + setDeltas(oldText: string, newText: string, newStart: number, newExtent: number): void { + this.oldText = oldText; + this.deltaText = newText; + this.deltaStart = newStart; + this.deltaEnd = newExtent; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..6df66b9cfde51d0d47c80b693b28f1f049c38b09 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import TextInputChannel, { Configuration, TextEditState, + TextInputMethodHandler, + TextInputType } from '../../embedding/engine/systemchannels/TextInputChannel'; +import inputMethod from '@ohos.inputMethod'; +import Log from '../../util/Log'; +import { EditingStateWatcher, ListenableEditingState } from './ListenableEditingState'; + +export default class TextInputPlugin implements EditingStateWatcher{ + private static TAG = "TextInputPlugin"; + private textInputChannel: TextInputChannel; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private mEditable: ListenableEditingState; + + constructor(textInputChannel: TextInputChannel) { + this.textInputChannel = textInputChannel; + this.mEditable = new ListenableEditingState(); + this.inputMethodController = inputMethod.getController(); + let textInputMethodHandler = new TextInputMethodHandlerImpl(this); + this.textInputChannel.setTextInputMethodHandler(textInputMethodHandler); + } + + public clearTextInputClient() { + this.textInputChannel.textInputMethodHandler.clearClient(); + } + setTextInputEditingState(state: TextEditState) { + + } + + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void { + this.textInputChannel.updateEditingState(this.inputTarget.id, this.mEditable.getStringCache(), + this.mEditable.getSelectionStart(), this.mEditable.getSelectionEnd(), + this.mEditable.getComposingStart(), this.mEditable.getComposingEnd()) + } + + detach(): void { + this.inputMethodController.detach((err) => { + if(err) { + Log.e(TextInputPlugin.TAG, "Failed to detach: " + JSON.stringify(err)); + } + }) + } + +} + +class TextInputMethodHandlerImpl implements TextInputMethodHandler { + private static TAG = "TextInputMethodHandlerImpl"; + private textConfig: inputMethod.TextConfig; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private configuration: Configuration; + private mEditable: ListenableEditingState; + private mRestartInputPending: boolean; + private plugin: EditingStateWatcher; + + private imcFlag: boolean = false; + + constructor(plugin: EditingStateWatcher) { + this.textConfig = { + inputAttribute: { + textInputType: 0, + enterKeyType: 1 + }}; + this.plugin = plugin; + } + + show(): void { + this.showTextInput(); + } + + hide(): void { + this.hideTextInput(); + } + + requestAutofill(): void { + + } + + finishAutofillContext(shouldSave: boolean): void { + + } + + setClient(textInputClientId: number, configuration: Configuration): void { + Log.d(TextInputMethodHandlerImpl.TAG,"textInputClientId: " + textInputClientId); + this.setTextInputClient(textInputClientId, configuration); + } + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void { + + } + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void { + + } + + setEditingState(editingState: TextEditState): void { + Log.d(TextInputMethodHandlerImpl.TAG, "text:" + editingState.text +" selectionStart:" + editingState.selectionStart + " selectionEnd:" + + editingState.selectionEnd + " composingStart:" + editingState.composingStart + " composingEnd" + editingState.composingEnd); + this.mEditable.updateTextInputState(editingState); + } + + clearClient(): void { + this.clearTextInputClient(); + } + + private async showTextInput(): Promise { + await this.attach(true); + if(this.imcFlag != true) { + this.listenKeyBoardEvent(); + } + this.inputMethodController.showTextInput().then(()=> { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in showing softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to show softKeyboard:" + JSON.stringify(err)); + }); + } + + private async hideTextInput(): Promise { + this.inputMethodController.hideTextInput().then(() => { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in hide softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to hide softKeyboard:" + JSON.stringify(err)); + }) + } + + async attach(showKeyboard: boolean): Promise { + try { + await this.inputMethodController.attach(showKeyboard, this.textConfig); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to attach:" + JSON.stringify(err)); + } + } + + setTextInputClient(client: number, configuration: Configuration): void { + this.configuration = configuration; + if(this.canShowTextInput()) { + this.inputTarget = new InputTarget(Type.FRAMEWORK_CLIENT, client); + } else { + this.inputTarget = new InputTarget(Type.NO_TARGET, client); + } + this.mEditable.removeEditingStateListener(this.plugin); + this.mEditable = new ListenableEditingState(); + + this.mRestartInputPending = true; + this.mEditable.addEditingStateListener(this.plugin); + } + + canShowTextInput(): boolean { + if(this.configuration == null || this.configuration.inputType == null) { + return true; + } + return this.configuration.inputType.type != TextInputType.NONE; + } + + listenKeyBoardEvent(): void { + try { + this.inputMethodController.on('insertText', (text) => { + Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); + this.mEditable.handleInsertTextEvent(text); + }); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteLeft', (length) => { + this.mEditable.handleDeleteEvent(false, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteRight', (length) => { + this.mEditable.handleDeleteEvent(true, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('sendFunctionKey', (functionKey) => { + this.mEditable.handleFunctionKey(functionKey); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('selectByRange', (range: inputMethod.Range) => { + this.mEditable.handleSelectByRange(range); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + Log.d(TextInputMethodHandlerImpl.TAG, "listenKeyBoardEvent success"); + this.imcFlag = true; + } + + cancelListenKeyBoardEvent(): void { + this.inputMethodController.off('insertText'); + this.inputMethodController.off('deleteLeft'); + this.inputMethodController.off('deleteRight'); + this.inputMethodController.off('sendFunctionKey'); + this.inputMethodController.off('selectByRange'); + } + + public clearTextInputClient(): void { + if(this.inputTarget.type == Type.VIRTUAL_DISPLAY_PLATFORM_VIEW) { + return; + } + this.mEditable.removeEditingStateListener(this.plugin); + this.configuration = null; + this.inputTarget = new InputTarget(Type.NO_TARGET, 0); + } +} + +enum Type { + NO_TARGET, + // InputConnection is managed by the TextInputPlugin, and events are forwarded to the Flutter + // framework. + FRAMEWORK_CLIENT, + // InputConnection is managed by a platform view that is presented on a virtual display. + VIRTUAL_DISPLAY_PLATFORM_VIEW, + PHYSICAL_DISPLAY_PLATFORM_VIEW, +} + +export class InputTarget { + type: Type; + id: number; + + constructor(type: Type, id: number) { + this.type = type; + this.id = id; + } + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..44c94a11aa2f132f6dd24b3484bb5ca9b59c940c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MouseCursorChannel, { MouseCursorMethodHandler } from '../../embedding/engine/systemchannels/MouseCursorChannel'; +import pointer from '@ohos.multimodalInput.pointer'; +import HashMap from '@ohos.util.HashMap'; +import Log from '../../util/Log'; +import { AsyncCallback } from '@ohos.base'; + +const TAG: string = "MouseCursorPlugin"; +export default class MouseCursorPlugin implements MouseCursorMethodHandler{ + private mView: MouseCursorViewDelegate; + + private mouseCursorChannel: MouseCursorChannel; + + private systemCursorConstants: HashMap; + + constructor(mouseCursorView: MouseCursorViewDelegate, mouseCursorChannel: MouseCursorChannel) { + this.mView = mouseCursorView; + this.mouseCursorChannel = mouseCursorChannel; + this.mouseCursorChannel.setMethodHandler(this); + } + + activateSystemCursor(kind: string): void { + this.mView.getWindowId((error, windowId) => { + if (windowId < 0) { + Log.w(TAG, "set point style failed windowId is invalid"); + return; + } + let pointStyle: pointer.PointerStyle = this.resolveSystemCursor(kind); + try { + pointer.setPointerStyle(windowId, pointStyle, (err: ESObject) => { + Log.i(TAG, "set point style success kind : " + kind); + }) + } catch (e) { + Log.e(TAG, "set point style failed : " + kind + " " + JSON.stringify(e)); + } + }); + } + + /** + * Return mouse cursor point style + * + *

This method guarantees to return a non-null object. + * + * @param kind mouse cursor type + * @returns point style + */ + private resolveSystemCursor(kind: string): pointer.PointerStyle { + if (this.systemCursorConstants == null) { + this.systemCursorConstants = new HashMap(); + this.systemCursorConstants.set("alias", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("allScroll", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("basic", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("cell", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("click", pointer.PointerStyle.HAND_POINTING); + this.systemCursorConstants.set("contextMenu", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("copy", pointer.PointerStyle.CURSOR_COPY); + this.systemCursorConstants.set("forbidden", pointer.PointerStyle.CURSOR_FORBID); + this.systemCursorConstants.set("grab", pointer.PointerStyle.HAND_OPEN); + this.systemCursorConstants.set("grabbing", pointer.PointerStyle.HAND_GRABBING); + this.systemCursorConstants.set("help", pointer.PointerStyle.HELP); + this.systemCursorConstants.set("move", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("none", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("noDrop", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("precise", pointer.PointerStyle.CROSS); + this.systemCursorConstants.set("text", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("resizeColum", pointer.PointerStyle.NORTH_SOUTH); + this.systemCursorConstants.set("resizeDown", pointer.PointerStyle.SOUTH); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeDownRight", pointer.PointerStyle.SOUTH_EAST); + this.systemCursorConstants.set("resizeLeft", pointer.PointerStyle.WEST); + this.systemCursorConstants.set("resizeLeftRight", pointer.PointerStyle.RESIZE_LEFT_RIGHT); + this.systemCursorConstants.set("resizeRight", pointer.PointerStyle.EAST); + this.systemCursorConstants.set("resizeRow", pointer.PointerStyle.WEST_EAST); + this.systemCursorConstants.set("resizeUp", pointer.PointerStyle.NORTH); + this.systemCursorConstants.set("resizeUpDown", pointer.PointerStyle.RESIZE_UP_DOWN); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeUpRight", pointer.PointerStyle.NORTH_EAST); + this.systemCursorConstants.set("resizeUpLeftDownRight", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("resizeUpRightDownLeft", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("verticalText", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("wait", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("zoomIn", pointer.PointerStyle.ZOOM_IN); + this.systemCursorConstants.set("zoomOut", pointer.PointerStyle.ZOOM_OUT); + } + let pointStyle:pointer.PointerStyle = this.systemCursorConstants.get(kind); + if (pointStyle === null) { + return pointer.PointerStyle.DEFAULT; + } + return pointStyle; + } + + /** + * Detaches the text input plugin from the platform views controller; + * + *

The MouseCursorPlugin instance should not be used after call this. + */ + destroy(): void { + this.mouseCursorChannel.setMethodHandler(null); + } +} + +/** + * Delegate interface for requesting the system to display a pointer icon object. + * + *

Typically implemented by an component, such as a{@code FlutterView} + */ +export interface MouseCursorViewDelegate { + /** + * get window id to set mouse style + *

component need to implement this interface to get windowId + * + * @param callback windowId + * */ + getWindowId(callback: AsyncCallback): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..faa3bc90e50c304744883689a532d0dc323bd714 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export class AccessibilityEventsDelegate { + private accessibilityBridge: AccessibilityBridge; + + requestSendAccessibilityEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + onAccessibilityHoverEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + setAccessibilityBridge (accessibilityBridge: AccessibilityBridge): void { + this.accessibilityBridge = accessibilityBridge; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets new file mode 100644 index 0000000000000000000000000000000000000000..64e8c7f780dc9253f3fd79c05663805a13c8d839 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; + +export class PlatformOverlayView { + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + + constructor(context: Context, width: Number, height: Number, accessibilityEventsDelegate: AccessibilityEventsDelegate) { + this.accessibilityEventsDelegate= accessibilityEventsDelegate; + } + + public onHoverEvent(): boolean { + return false; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets new file mode 100644 index 0000000000000000000000000000000000000000..ddf5f59a71c4d1c7d51082bcf104990e0faa08c6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DynamicView } from '../../view/DynamicView/dynamicView' + +/** A handle to an DynamicView to be embedded in the Flutter hierarchy. */ +export default abstract class PlatformView { + /** Returns the DynamicView to be embedded in the Flutter hierarchy. */ + abstract getView(): DVModel; + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is + * associated with the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} can now + * render a UI and interact with the user. + * + *

Some platform views may have unusual dependencies on the {@link View} that renders Flutter + * UIs, such as unique keyboard interactions. That {@link View} is provided here for those + * purposes. Use of this {@link View} should be avoided if it is not absolutely necessary, because + * depending on this {@link View} will tend to make platform view code more brittle to future + * changes. + */ + onFlutterViewAttached(dvModel: DVModel): void {} + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is detached + * and disassociated from the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} no longer + * has a rendering surface, or a user interaction surface of any kind. + * + *

This platform view must release any references related to the DynamicView that was + * provided in {@link #onFlutterViewAttached(View)}. + */ + onFlutterViewDetached(): void {} + + /** + * Dispose this platform view. + * + *

The {@link PlatformView} object is unusable after this method is called. + * + *

Plugins implementing {@link PlatformView} must clear all references to the View object and + * the PlatformView after this method is called. Failing to do so will result in a memory leak. + * + *

References related to the DynamicView attached in {@link + * #onFlutterViewAttached(View)} must be released in {@code dispose()} to avoid memory leaks. + */ + abstract dispose(): void; + + /** + * Callback fired when the platform's input connection is locked, or should be used. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionLocked(): void {} + + /** + * Callback fired when the platform input connection has been unlocked. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionUnlocked(): void {} +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..373a7ea5a5906c812c330762fd3825d4ce420201 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from '../common/MessageCodec'; +import PlatformView from './PlatformView' +import common from '@ohos.app.ability.common'; + +export default abstract class PlatformViewFactory { + private createArgsCodec: MessageCodec; + + /** @param createArgsCodec the codec used to decode the args parameter of {@link #create}. */ + constructor(createArgsCodec: MessageCodec) { + this.createArgsCodec = createArgsCodec; + } + + /** + * Creates a new Dynamic be embedded in the Flutter hierarchy. + * + * @param context the context to be used when creating the view, this is different than + * FlutterView's context. + * @param viewId unique identifier for the created instance, this value is known on the Dart side. + * @param args arguments sent from the Flutter app. The bytes for this value are decoded using the + * createArgsCodec argument passed to the constructor. This is null if createArgsCodec was + * null, or no arguments were sent from the Flutter app. + */ + public abstract create(context: common.Context, viewId: number, args: ESObject): PlatformView; + + /** Returns the codec to be used for decoding the args parameter of {@link #create}. */ + getCreateArgsCodec(): MessageCodec { + return this.createArgsCodec; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c49f5eeaddb54cece120df8eea307c69ad76ebf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PlatformViewFactory from './PlatformViewFactory' + +/** + * Registry for platform view factories. + * + *

Plugins can register factories for specific view types. + */ +export default interface PlatformViewRegistry { + /** + * Registers a factory for a platform view. + * + * @param viewTypeId unique identifier for the platform view's type. + * @param factory factory for creating platform views of the specified type. + * @return true if succeeded, false if a factory is already registered for viewTypeId. + */ + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets new file mode 100644 index 0000000000000000000000000000000000000000..98cb247d890cbe65150feb84242c01128047e7f9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import PlatformViewFactory from './PlatformViewFactory' +import PlatformViewRegistry from './PlatformViewRegistry' + +export default class PlatformViewRegistryImpl implements PlatformViewRegistry { + // Maps a platform view type id to its factory. + private viewFactories: HashMap; + + constructor() { + this.viewFactories = new HashMap(); + } + + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { + if (this.viewFactories.hasKey(viewTypeId)) { + return false; + } + + this.viewFactories.set(viewTypeId, factory); + return true; + } + + getFactory(viewTypeId: string): PlatformViewFactory { + return this.viewFactories.get(viewTypeId); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..c34d9bcce565e65f3eebb5cccf355a9d3f366fac --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor'; +import { DVModel, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; +import { RootDvModeManager } from './RootDvModelManager'; +import matrix4 from '@ohos.matrix4' +import Log from '../../util/Log'; + +const TAG: string = "PlatformViewWrapper"; +export class PlatformViewWrapper { + private prevLeft: number; + private prevTop: number; + private left: number; + private top: number; + private bufferWidth: number; + private bufferHeight: number; + private touchProcessor: OhosTouchProcessor; + + // private onTouch = (touchEvent: TouchEvent) => { + // switch (touchEvent.type) { + // case TouchType.Down: + // this.prevLeft = this.left; + // this.prevTop = this.top; + // this.model.params.translateX = this.left; + // this.model.params.translateY = this.top; + // break; + // case TouchType.Move: + // this.model.params.translateX = this.prevLeft; + // this.model.params.translateY = this.prevTop; + // this.prevLeft = this.left; + // this.prevTop = this.top; + // break; + // case TouchType.Up: + // case TouchType.Cancel: + // default: + // break; + // } + // } + + private model : DVModel = createDVModelFromJson( new DVModelParam("Column", [])); + + public setTouchProcessor(newTouchProcessor: OhosTouchProcessor): void { + this.touchProcessor = newTouchProcessor; + } + + constructor() { + } + + public getDvModel(): DVModel { + return this.model; + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + + public setLayoutParams(parameters : DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + this.setParams(this.model.params, "marginLeft", this.getParams(parameters, "marginLeft")); + this.setParams(this.model.params, "marginTop", this.getParams(parameters, "marginTop")); + this.left = this.getParams(parameters, "marginLeft"); + this.top = this.getParams(parameters, "marginTop"); + + this.setParams(this.model.params, "width", this.getParams(parameters, "width")); + this.setParams(this.model.params, "height", this.getParams(parameters, "height")); + + // this.model.params.marginLeft = parameters.marginLeft; + // this.model.params.marginTop = parameters.marginTop; + // this.left = parameters.marginLeft; + // this.top = parameters.marginTop;; + + // this.model.params.width = parameters.width; + // this.model.params.height = parameters.height; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } +} + +class DVModelParam { + compType: string + children: [] + + constructor(compType: string, children: []) { + this.compType = compType; + this.children = children; + } +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..62888046c561533a3ea096c77ce7f3f634503e4c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export interface PlatformViewsAccessibilityDelegate { + /** + * Returns the root of the view hierarchy for the platform view with the requested id, or null if + * there is no corresponding view. + */ + getPlatformViewById(viewId: number): Object; + + /** Returns true if the platform view uses virtual displays. */ + usesVirtualDisplay(id: number): boolean; + + /** + * Attaches an accessibility bridge for this platform views accessibility delegate. + * + *

Accessibility events originating in platform views belonging to this delegate will be + * delegated to this accessibility bridge. + */ + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void; + + /** + * Detaches the current accessibility bridge. + * + *

Any accessibility events sent by platform views belonging to this delegate will be ignored + * until a new accessibility bridge is attached. + */ + detachAccessibilityBridge(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets new file mode 100644 index 0000000000000000000000000000000000000000..b77917fc75a9baaf6c7f88a4df6fd4349a5b789c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { PlatformViewsAccessibilityDelegate } from './PlatformViewsAccessibilityDelegate'; +import PlatformViewsChannel, { + PlatformViewBufferResized, + PlatformViewCreationRequest, + PlatformViewResizeRequest, + PlatformViewsHandler, PlatformViewTouch, PlatformViewBufferSize +} from '../../../ets/embedding/engine/systemchannels/PlatformViewsChannel'; +import PlatformView from './PlatformView'; +import { DVModel, DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import display from '@ohos.display'; +import { FlutterView } from '../../view/FlutterView'; +import { TextureRegistry } from '../../view/TextureRegistry'; +import TextInputPlugin from '../editing/TextInputPlugin'; +import { PlatformOverlayView } from './PlatformOverlayView'; +import { PlatformViewWrapper } from './PlatformViewWrapper'; +import { FlutterOverlaySurface } from '../../embedding/engine/FlutterOverlaySurface'; +import HashSet from '@ohos.util.HashSet'; +import PlatformViewRegistry from './PlatformViewRegistry'; +import PlatformViewRegistryImpl from './PlatformViewRegistryImpl'; +import DartExecutor from '../../embedding/engine/dart/DartExecutor'; +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; +import AccessibilityBridge from '../../view/AccessibilityBridge'; +import { RootDvModeManager } from './RootDvModelManager'; +import { FlutterMutatorView } from '../../embedding/engine/mutatorsstack/FlutterMutatorView'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log' +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor' +import PlatformViewFactory from './PlatformViewFactory' +import { ByteBuffer } from '../../util/ByteBuffer'; + +const TAG = "PlatformViewsController" + +export default class PlatformViewsController implements PlatformViewsAccessibilityDelegate, PlatformViewsHandler { + private registry: PlatformViewRegistryImpl; + private context: Context; + private flutterView: FlutterView; + private textureRegistry: TextureRegistry; + private textInputPlugin: TextInputPlugin; + private platformViewsChannel: PlatformViewsChannel; + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + private nextOverlayLayerId: number = 0; + private ohosTouchProcessor: OhosTouchProcessor; + private usesSoftwareRendering: boolean = false; + + private platformViews: Map; + private overlayLayerViews: Map; + private viewWrappers: Map; + private currentFrameUsedOverlayLayerIds: HashSet; + private currentFrameUsedPlatformViewIds: HashSet; + private rootDvModel = RootDvModeManager.getRootDvMode(); + private platformViewParent: Map; + + constructor() { + this.registry = new PlatformViewRegistryImpl(); + this.accessibilityEventsDelegate = new AccessibilityEventsDelegate(); + this.overlayLayerViews = new Map(); + this.currentFrameUsedOverlayLayerIds = new HashSet(); + this.currentFrameUsedPlatformViewIds = new HashSet(); + this.viewWrappers = new Map(); + this.platformViews = new Map(); + this.platformViewParent = new Map(); + } + + + getPlatformViewById(viewId: number): Object { + throw new Error('Method not implemented.'); + } + + usesVirtualDisplay(id: number): boolean { + throw new Error('Method not implemented.'); + } + + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void { + throw new Error('Method not implemented.'); + } + + detachAccessibilityBridge(): void { + throw new Error('Method not implemented.'); + } + + createForPlatformViewLayer(request: PlatformViewCreationRequest): void { + Log.i(TAG, "Enter createForPlatformViewLayer"); + this.ensureValidRequest(request); + + let platformView: PlatformView = this.createPlatformView(request, false); + + this.configureForHybridComposition(platformView, request); + } + + dispose(viewId: number): void { + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Disposing unknown platform view with id: " + viewId); + return; + } + this.platformViews.delete(viewId); + + try { + platformView.dispose(); + } catch (err) { + Log.e(TAG, "Disposing platform view threw an exception", err); + } + + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper != null) { + this.viewWrappers.delete(viewId); + } + + let parentView: FlutterMutatorView = this.platformViewParent.get(viewId); + if (parentView != null) { + this.platformViewParent.delete(viewId); + } + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void { + let physicalWidth: number = this.toPhysicalPixels(request.newLogicalWidth); + let physicalHeight: number = this.toPhysicalPixels(request.newLogicalHeight); + let viewId: number = request.viewId; + Log.i(TAG, `Resize viewId ${viewId}, pw:${physicalWidth}, ph:${physicalHeight},lw:${request.newLogicalWidth}, lh:${request.newLogicalHeight}`); + + let platformView: PlatformView = this.platformViews.get(viewId); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (platformView == null || viewWrapper == null) { + Log.e(TAG, "Resizing unknown platform view with id: " + viewId); + return; + } + + let viewWrapperLayoutParams: DVModelParameters = viewWrapper.getDvModel().getLayoutParams(); + if (physicalWidth) { + this.setParams(viewWrapperLayoutParams, "width", physicalWidth); + // viewWrapperLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(viewWrapperLayoutParams, "height", physicalHeight); + // viewWrapperLayoutParams.height = physicalHeight; + } + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView != null) { + let embeddedViewLayoutParams = embeddedView.getLayoutParams(); + if (physicalWidth) { + this.setParams(embeddedViewLayoutParams, "width", physicalWidth); + // embeddedViewLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(embeddedViewLayoutParams, "height", physicalHeight); + // embeddedViewLayoutParams.height = physicalHeight; + } + } + + onComplete.run(new PlatformViewBufferSize(request.newLogicalWidth, request.newLogicalHeight)); + } + + offset(viewId: number, top: number, left: number): void { + Log.i(TAG, `Offset is id${viewId}, t:${top}, l:${left}`); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper == null) { + Log.e(TAG, "Setting offset for an unknown platform view with id: " + viewId); + return; + } + + let physicalTop = this.toPhysicalPixels(top); + let physicalLeft = this.toPhysicalPixels(left); + let params = viewWrapper.getDvModel().params; + this.setParams(params, "marginTop", physicalTop); + this.setParams(params, "marginLeft", physicalLeft); + // params.marginTop = physicalTop; + // params.marginLeft = physicalLeft; + viewWrapper.setLayoutParams(params); + } + + onTouch(touch: PlatformViewTouch): void { + let viewId: number = touch.viewId; + let density: number = display.getDefaultDisplaySync().densityDPI; + + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Sending touch to an unknown platform view with id: " + viewId); + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + Log.e(TAG, "Sending touch to a null dv model with id: " + viewId); + } + Log.e(TAG, "Sending touch to a dv model with id: " + viewId.toString()); + sendEventByKey(viewId.toString(), 10, ""); + } + + setDirection(viewId: number, direction: number): void { + if (!this.validateDirection(direction)) { + throw new Error("Trying to set unknown direction value: " + + direction + + "(view id: " + + viewId + + ")"); + } + + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + this.setParams(embeddedView.params, "direction", direction); + // embeddedView.params.direction = direction; + } + + validateDirection(direction:number):boolean { + return direction == Direction.Ltr || direction == Direction.Rtl || direction == Direction.Auto; + } + + clearFocus(viewId: number): void { + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + focusControl.requestFocus("flutterXComponent"); + } + synchronizeToNativeViewHierarchy(yes: boolean): void { + throw new Error('Method not implemented.'); + } + + public createForTextureLayer(request: PlatformViewCreationRequest): number { + Log.i(TAG, "Enter createForTextureLayer"); + this.ensureValidRequest(request); + + let viewId: number = request.viewId; + if (this.viewWrappers.get(request.viewId) != null) { + throw new Error( + "Trying to create an already created platform view, view id: " + viewId); + } + + let platformView: PlatformView = this.createPlatformView(request, true); + let dynamicView: DVModel = platformView.getView(); + return this.configureForTextureLayerComposition(platformView, request); + } + + private ensureValidRequest(request: PlatformViewCreationRequest): void { + if (!this.validateDirection(request.direction)) { + throw new Error("Trying to create a view with unknown direction value: " + + request.direction + + "(view id: " + + request.viewId + + ")") + } + } + + private createPlatformView(request: PlatformViewCreationRequest, wrapContext: boolean): PlatformView { + Log.i(TAG, "Enter createPlatformView"); + const viewFactory: PlatformViewFactory = this.registry.getFactory(request.viewType); + if (viewFactory == null) { + throw new Error("Trying to create a platform view of unregistered type: " + request.viewType) + } + + let createParams: ESObject = null; + if (request.params != null) { + let byteParas : ByteBuffer = request.params as ByteBuffer; + createParams = viewFactory.getCreateArgsCodec().decodeMessage(byteParas.buffer); + } + + let mutableContext: common.Context = this.context; + let platformView = viewFactory.create(mutableContext, request.viewId, createParams); + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView == null) { + throw new Error("PlatformView#getView() returned null, but an dynamic view reference was expected."); + } + + this.setParams(embeddedView.params, "direction", request.direction); + // embeddedView.params.direction = request.direction; + + this.platformViews.set(request.viewId, platformView); + return platformView; + } + + // Configures the view for Hybrid Composition mode. + private configureForHybridComposition(platformView: PlatformView, request: PlatformViewCreationRequest): void { + Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId); + } + + private configureForTextureLayerComposition(platformView: PlatformView, request: PlatformViewCreationRequest): number { + Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId); + + let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); + let textureId: number = 0; + + let physicalTop: number = this.toPhysicalPixels(request.logicalTop); + let physicalLeft: number = this.toPhysicalPixels(request.logicalLeft); + + Log.i(TAG, `View pW:${request.logicalWidth}, pH:${request.logicalHeight}, pT:${physicalTop}, pL:${physicalLeft}`); + + let param: DVModelParameters = new DVModelParameters(); + + this.setParams(param, "marginLeft", physicalLeft); + this.setParams(param, "marginTop", physicalTop); + // param.marginLeft = physicalLeft; + // param.marginTop = physicalTop; + + let model = platformView.getView(); + if (request.logicalWidth != null) { + let physicalWidth: number = this.toPhysicalPixels(request.logicalWidth); + this.setParams(model.params, "width", physicalWidth); + this.setParams(param, "width", physicalWidth); + // model.params.width = physicalWidth; + // param.width = physicalWidth; + } + + if (request.logicalHeight != null) { + let physicalHeight: number = this.toPhysicalPixels(request.logicalHeight); + this.setParams(model.params, "height", physicalHeight); + this.setParams(param, "height", physicalHeight); + // model.params.height = physicalHeight; + // param.height = physicalHeight; + } + + viewWrapper.setLayoutParams(param); + viewWrapper.addDvModel(model); + + RootDvModeManager.addDvModel(viewWrapper.getDvModel()); + this.viewWrappers.set(request.viewId, viewWrapper); + Log.i(TAG, "Create platform view success"); + + return textureId; + } + + public attach(context: Context, textureRegistry: TextureRegistry, dartExecutor: DartExecutor): void { + if (this.context != null) { + + } + this.context = context; + this.textureRegistry = textureRegistry; + this.platformViewsChannel = new PlatformViewsChannel(dartExecutor); + this.platformViewsChannel.setPlatformViewsHandler(this); + } + + public detach(): void { + if (this.platformViewsChannel != null) { + this.platformViewsChannel.setPlatformViewsHandler(null); + } + this.destroyOverlaySurfaces(); + this.platformViewsChannel = null; + this.context = null; + this.textureRegistry = null; + } + + public attachToView() { + for (let wrapper of this.viewWrappers.values()) { + this.rootDvModel.model.children.push(wrapper.getDvModel()); + } + for (let mutator of this.platformViewParent.values()) { + this.rootDvModel.model.children.push(mutator.getDvModel()); + } + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewAttached(this.rootDvModel.model); + } + } + + public detachFromView(): void { + for (let index = 0; index < this.viewWrappers.size; index++) { + this.rootDvModel.model.children.pop(); + } + for (let index = 0; index < this.platformViewParent.size; index++) { + this.rootDvModel.model.children.pop(); + } + this.destroyOverlaySurfaces(); + this.removeOverlaySurfaces(); + this.rootDvModel = null; + + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewDetached(); + } + } + + public attachTextInputPlugin(textInputPlugin: TextInputPlugin): void { + this.textInputPlugin = textInputPlugin; + } + + public detachTextInputPlugin(): void { + this.textInputPlugin == null; + } + + public getRegistry(): PlatformViewRegistry { + return this.registry; + } + + public onDetachedFromNapi(): void { + this.diposeAllViews(); + } + + public onPreEngineRestart(): void { + this.diposeAllViews(); + } + + private getDisplayDensity(): number { + return display.getDefaultDisplaySync().densityPixels; + } + private toPhysicalPixels(logicalPixels: number): number { + return Math.round(px2vp(logicalPixels * this.getDisplayDensity())); + } + + private toLogicalPixelsByDensity(physicalPixels: number, displayDensity: number): number { + return Math.round(physicalPixels / displayDensity); + } + + private toLogicalPixels(physicalPixels: number): number { + return this.toLogicalPixelsByDensity(physicalPixels, this.getDisplayDensity()); + } + + + private diposeAllViews(): void { + } + + private initializeRootImageViewIfNeeded(): void { + } + + initializePlatformViewIfNeeded(viewId: number): void { + let platformView: PlatformView = this.platformViews[viewId]; + if (platformView == null) { + throw new Error("Platform view hasn't been initialized from the platform view channel."); + } + if (this.platformViewParent[viewId] == null) { + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + throw new Error("PlatformView#getView() returned null, but an ohos dv model reference was expected."); + } + let parentView: FlutterMutatorView = new FlutterMutatorView(); + parentView.setOnDescendantFocusChangeListener(() => { + this.platformViewsChannel.invokeViewFocused(viewId); + }, () => { + if (this.textInputPlugin != null) { + this.textInputPlugin.clearTextInputClient(); + } + }); + } + + public onDisplayOverlaySurface(id: number, x: number, y: number, width: number, height: number): void { + } + + public onBeginFrame(): void { + this.currentFrameUsedOverlayLayerIds.clear(); + this.currentFrameUsedPlatformViewIds.clear(); + } + + public onEndFrame(): void { + } + + private finishFrame(isFrameRenderedUsingImageReaders: boolean): void { + } + + public createOverlaySurfaceByPlatformOverlayView(imageView: PlatformOverlayView) { + let id = this.nextOverlayLayerId++; + this.overlayLayerViews.set(id, imageView); + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + public createOverlaySurface(): FlutterOverlaySurface { + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + private destroyOverlaySurfaces(): void { + } + + private removeOverlaySurfaces(): void { + if (!(this.flutterView instanceof FlutterView)) { + return; + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cc2cb0b2cc44032d2384282013785d150162bc9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DVModelContainer, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +@Component +struct XComponentStruct { + private context: ESObject; + + build() { + XComponent({ id: 'flutterXComponent', type: 'texture', libraryname: 'flutter' }) + .onLoad((context) => { + this.context = context; + }) + .onDestroy(() => { + }) + } +} + +interface $$type { + param: DVModelParameters +} + +@Builder +function BuildXComponentStruct($$: $$type) { + XComponentStruct(); +} + +class DVModelJson { + compType: string + children: Array + attributes: ESObject + + constructor(compType: string, children: Array, attributes: ESObject) { + this.compType = compType + this.children = children + this.attributes = attributes + } +} + +export class RootDvModeManager { + private static xComponentModel: ESObject = + { + compType: "xComponent", + build: BuildXComponentStruct + }; + private static model: DVModel = createDVModelFromJson(new DVModelJson("Stack", [RootDvModeManager.xComponentModel], { + alignContent: Alignment.TopStart + },) + + ); + private static container: DVModelContainer = new DVModelContainer(RootDvModeManager.model); + + public static getRootDvMode(): DVModelContainer { + return RootDvModeManager.container; + } + + public static addDvModel(model: DVModel): void { + RootDvModeManager.container.model.children.push(model); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets new file mode 100644 index 0000000000000000000000000000000000000000..99a7d4b522caa6daf09b06e6feb40bcd6203abd3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * A byte buffer. + * + * Supports the following data types: + * - Bool + * - Int (8, 16, 32, 64) + * - Uint (8, 16, 32, 64) + * - BigInt (64) + * - String (utf8, utf16, and delimited) + * - TypedArray + * + */ +export class ByteBuffer { + + /** + * Creates a byte buffer. + * @param source The data source. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns A byte buffer. + */ + static from(source: ArrayBuffer, byteOffset?: number, byteLength?: number): ByteBuffer { + // if (ArrayBuffer.isView(source)) { + // byteOffset = source.byteOffset + (byteOffset || 0) + // } + const byteBuffer = new ByteBuffer() + byteBuffer.dataView = byteLength === undefined ? new DataView(source, byteOffset) : new DataView(source, byteOffset, Math.min(source.byteLength, byteLength)) + byteBuffer.mByteOffset = byteBuffer.dataView.byteOffset + return byteBuffer + } + + /** + * The dataView. + */ + private dataView: DataView + + /** + * The byte offset. + */ + mByteOffset: number = 0 + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteOffset(): number { + return this.mByteOffset + } + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteLength(): number { + return this.dataView.byteLength + } + + /** + * The number of remaining bytes. + * @returns The number of bytes remaining. + */ + get bytesRemaining(): number { + return this.dataView.byteLength - this.mByteOffset + } + + hasRemaining(): boolean { + return this.mByteOffset < this.dataView.byteLength; + } + + get buffer(): ArrayBuffer { + const dataBuffer = new DataView(new ArrayBuffer(this.mByteOffset)); + for (let i = 0; i < this.mByteOffset; i++) { + dataBuffer.setUint8(i, this.dataView.getUint8(i)); + } + return dataBuffer.buffer + } + + /** + * Skips the byte offset. + * @param byteLength The byte length. + */ + skip(byteLength: number): void { + this.mByteOffset += byteLength + } + + /** + * Resets the byte offset. + */ + reset(): void { + this.mByteOffset = this.dataView.byteOffset + } + + /** + * Clears the byte buffer. + */ + clear(): void { + this.getUint8Array(0).fill(0) + } + + /** + * check buffer capacity. + */ + checkWriteCapacity(slen: number): void { + if (this.mByteOffset + slen > this.dataView.byteLength) { + let checkBuffer = new DataView(new ArrayBuffer(this.dataView.byteLength + slen + 512)); + for (let i = 0; i < this.mByteOffset; i++) { + checkBuffer.setUint8(i, this.dataView.getUint8(i)); + } + this.dataView = checkBuffer; + } + } + + /** + * Gets a boolean. + * @param byteOffset The byte offset. + */ + getBool(byteOffset: number): boolean { + return this.getInt8(byteOffset) !== 0 + } + + /** + * Reads the next boolean. + */ + readBool(): boolean { + return this.getInt8(this.mByteOffset++) !== 0 + } + + /** + * Sets a boolean. + * @param byteOffset The byte offset. + * @param value The value. + */ + setBool(byteOffset: number, value: boolean): void { + this.dataView.setInt8(byteOffset, value ? 1 : 0) + } + + /** + * Writes the next boolean. + * @param value The value. + */ + writeBool(value: boolean): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value ? 1 : 0) + } + + /** + * Gets an signed byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getInt8(byteOffset: number): number { + return this.dataView.getInt8(byteOffset) + } + + /** + * Reads the next signed byte. + * @returns The value. + */ + readInt8(): number { + return this.getInt8(this.mByteOffset++) + } + + /** + * Sets a signed byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setInt8(byteOffset: number, value: number): void { + this.dataView.setInt8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeInt8(value: number): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value) + } + + /** + * Gets an unsigned byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getUint8(byteOffset: number): number { + return this.dataView.getUint8(byteOffset) + } + + /** + * Reads the next unsigned byte. + * @returns The value. + */ + readUint8(): number { + return this.getUint8(this.mByteOffset++) + } + + /** + * Sets an unsigned byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8(byteOffset: number, value: number): void { + this.dataView.setUint8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeUint8(value: number): void { + this.checkWriteCapacity(1) + this.setUint8(this.mByteOffset++, value) + } + + /** + * Gets an signed short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt16(byteOffset, littleEndian) + } + + /** + * Reads the next signed short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt16(littleEndian?: boolean): number { + const value = this.getInt16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets a signed short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setInt16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an unsigned short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint16(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint16(littleEndian?: boolean): number { + const value = this.getUint16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets an unsigned short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setUint16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an signed integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt32(byteOffset, littleEndian) + } + + /** + * Reads the next signed integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt32(littleEndian?: boolean): number { + const value = this.getInt32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a signed integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setInt32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets an unsigned integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint32(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint32(littleEndian?: boolean): number { + const value = this.getUint32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets an unsigned integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setUint32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a float. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat32(byteOffset, littleEndian) + } + + /** + * Reads the next float. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat32(littleEndian?: boolean): number { + const value = this.getFloat32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a float. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat32(byteOffset, value, littleEndian) + } + + /** + * Writes the next float. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setFloat32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a double. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat64(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat64(byteOffset, littleEndian) + } + + /** + * Reads the next double. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat64(littleEndian?: boolean): number { + const value = this.getFloat64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a double. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat64(byteOffset, value, littleEndian) + } + + /** + * Writes the next double. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setFloat64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigInt64(byteOffset, littleEndian) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigInt64(littleEndian?: boolean): bigint { + const value = this.getBigInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigInt64(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigInt64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigUint64(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigUint64(littleEndian?: boolean): bigint { + const value = this.getBigUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigUint64(byteOffset, value, littleEndian) + } + + /** + * Writes the next unsigned long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigUint64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigInt64(byteOffset, littleEndian)) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt64(littleEndian?: boolean): number { + const value = this.getInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigInt64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigUint64(byteOffset, littleEndian)) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint64(littleEndian?: boolean): number { + const value = this.getUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigUint64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { + return new Uint8Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned bytes. + * @param byteLength The byte length. + * @returns The value. + */ + readUint8Array(byteLength?: number): Uint8Array { + const value = this.getUint8Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8Array(byteOffset: number, value: Uint8Array): void { + const byteLength = value.byteLength + this.getUint8Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint8Array(value: Uint8Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint8Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets an array of unsigned shorts. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { + if (byteLength !== undefined) { + byteLength = Math.floor(byteLength / 2) + } + return new Uint16Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned shorts. + * @param byteLength The byte length. + * @returns The value. + */ + readUint16Array(byteLength?: number): Uint16Array { + const value = this.getUint16Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint16Array(byteOffset: number, value: Uint16Array): void { + const byteLength = value.byteLength + this.getUint16Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint16Array(value: Uint16Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint16Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets a string. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { + const decoder = new util.TextDecoder(byteEncoding || "utf-8") + const encoded = this.getUint8Array(byteOffset, byteLength) + return decoder.decode(encoded) + } + + /** + * Reads the next string. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + readString(byteLength?: number, byteEncoding?: string): string { + const value = this.getString(this.mByteOffset, byteLength, byteEncoding) + if (byteLength === undefined) { + this.mByteOffset = this.dataView.byteLength + } else { + this.mByteOffset += byteLength + } + return value + } + + /** + * Sets a string. + * @param byteOffset The byte offset. + * @param value The string. + * @param byteEncoding The byte encoding. + * @returns The byte length. + */ + setString(byteOffset: number, value: string, byteEncoding?: string, write?: boolean): number { + if (byteEncoding && byteEncoding !== "utf-8") { + throw new TypeError("String encoding '" + byteEncoding + "' is not supported") + } + const encoder = new util.TextEncoder() + const byteLength = Math.min(this.dataView.byteLength - byteOffset, value.length * 4) + if (write) { + this.checkWriteCapacity(byteLength) + } + const destination = this.getUint8Array(byteOffset, byteLength) + const written = encoder.encodeInto(value, destination).written + return written || 0 + } + + /** + * Writes the next a string. + * @param value The string. + * @param byteEncoding The byte encoding. + */ + writeString(value: string, byteEncoding?: string): void { + const byteLength = this.setString(this.mByteOffset, value, byteEncoding, true) + this.mByteOffset += byteLength + } + + /** + * Formats to a string. + * @param format The string format. + * @returns The string. + */ + toString(format?: string): string { + return [...this.getUint8Array(0)].map((byte: number) => { + switch(format) { + case "hex": + return ("00" + byte.toString(16)).slice(-2) + default: + return byte.toString(10) + } + }).join(" ") + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets new file mode 100644 index 0000000000000000000000000000000000000000..437b52f18049b9ba77e47350033482a06368c5c4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HiLog from '@ohos.hilog'; + +const DOMAIN: number = 0x00FF; +const TAG = "Flutter"; +const SYMBOL = " --> "; +// const FILTER_KEYS = [ +// new RegExp('hide', "gi") +// ] + +// export function filterKey(target: any, propKey: string, descriptor: PropertyDescriptor) { +// const original = descriptor.value; +// descriptor.value = function (...args: string[]) { +// let filterResult = args.map((str) => { +// let tempStr = str +// FILTER_KEYS.forEach((filterKey) => tempStr = tempStr.replace(filterKey, "**")) +// return tempStr +// }); +// const result = original.call(this, ...filterResult); +// return result; +// }; +// } + +/** + * Basic log class + */ +export default class Log { + /** + * Outputs debug-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static d(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.DEBUG)) { + HiLog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs info-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static i(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.INFO)) { + HiLog.info(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs warning-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static w(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.WARN)) { + HiLog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs error-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static e(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.ERROR)) { + HiLog.error(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs fatal-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static f(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.FATAL)) { + HiLog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Checks whether logs of the specified tag, and level can be printed. + * + * @param tag Identifies the log tag. + * @param level log level + * @since 7 + */ + private static isLoggable(level: HiLog.LogLevel): boolean { + return HiLog.isLoggable(DOMAIN, TAG, level); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..1899f74069a24a3e250378b11ac1c9492f03b8f3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../plugin/common/BinaryMessenger'; +import StringUtils from './StringUtils'; + +export default class MessageChannelUtils { + static resizeChannelBuffer(messenger: BinaryMessenger, channel: string, newSize: number) { + const dataStr = `resize\r${channel}\r${newSize}` + messenger.send(BasicMessageChannel.CHANNEL_BUFFERS_CHANNEL, StringUtils.stringToArrayBuffer(dataStr)); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..691ea0f360b40adb266bde566c2f66292a2aa0ff --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import common from '@ohos.app.ability.common'; +import fs from '@ohos.file.fs'; +import Log from './Log'; + +/** + * ohos路径获取工具 + */ +const TAG: string = "PathUtils"; + +export default class PathUtils { + static getFilesDir(context: common.Context): string { + return context.filesDir; + } + + static getCacheDirectory(context: common.Context): string { + return context.cacheDir; + } + + static getDataDirectory(context: common.Context): string { + const name = "flutter"; + const flutterDir = context.filesDir + "/" + name; + if (!fs.accessSync(flutterDir)) { + try { + fs.mkdirSync(flutterDir); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + return null; + } + } + return flutterDir; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeb7c554c30b5d3625851afc214dda8d31da9917 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * 默认字符串工具 + */ +export default class StringUtils { + static stringToArrayBuffer(str: string): ArrayBuffer { + let textEncoder = new util.TextEncoder("utf-8"); + return textEncoder.encodeInto(str).buffer; + } + + static arrayBufferToString(buffer: ArrayBuffer): string { + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true }) + return textDecoder.decode(new Uint8Array(buffer)) + } + + static isNotEmpty(str: string): boolean { + return str && str.length > 0; + } + + static isEmpty(str: string): boolean { + return (!str) || str.length == 0; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3879f4a40ea307f7491a4808ad3b816cc98b13e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class ToolUtils { + static isObj(object: Object): boolean { + return object && typeof (object) == 'object'; + } + + static implementsInterface(obj: ESObject, method: string): boolean { + return Reflect.has(obj, method) && typeof obj[method] === 'function' + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets new file mode 100644 index 0000000000000000000000000000000000000000..3caaadea7aa0cb84be3542be9c4595139cd25af4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hiTraceMeter from '@ohos.hiTraceMeter' + +export class TraceSection { + + static taskId: number = 1; + + private static cropSectionName(sectionName: string): string { + return sectionName.length < 124 ? sectionName : sectionName.substring(0, 124) + "..."; + } + + /** + * Wraps Trace.beginSection to ensure that the line length stays below 127 code units. + * + * @param sectionName The string to display as the section name in the trace. + */ + public static begin(sectionName: string): void { + hiTraceMeter.startTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId++); + } + + /** Wraps Trace.endSection. */ + public static end(sectionName: string): void { + hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e08f41fe9171658365b4e2c806b075807ddc423 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class AccessibilityBridge { + constructor(){ + + } +} + +export enum Action { + TAP = 1 << 0, + LONG_PRESS = 1 << 1, + SCROLL_LEFT = 1 << 2, + SCROLL_RIGHT = 1 << 3, + SCROLL_UP = 1 << 4, + SCROLL_DOWN = 1 << 5, + INCREASE = 1 << 6, + DECREASE = 1 << 7, + SHOW_ON_SCREEN = 1 << 8, + MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 << 9, + MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 << 10, + SET_SELECTION = 1 << 11, + COPY = 1 << 12, + CUT = 1 << 13, + PASTE = 1 << 14, + DID_GAIN_ACCESSIBILITY_FOCUS = 1 << 15, + DID_LOSE_ACCESSIBILITY_FOCUS = 1 << 16, + CUSTOM_ACTION = 1 << 17, + DISMISS = 1 << 18, + MOVE_CURSOR_FORWARD_BY_WORD = 1 << 19, + MOVE_CURSOR_BACKWARD_BY_WORD = 1 << 20, + SET_NEXT = 1 << 21, +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets new file mode 100644 index 0000000000000000000000000000000000000000..f95a9c04a7a44a99505b9882ba1291e7bfcb1604 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import matrix4 from '@ohos.matrix4'; + +/** + * Dynamic View creation + * from a recursive data structure + * + * exported @Component: DynamicView + * exported view model classes: + * - DVModelContainer + * - DVModel + * - DVModelParameters + * - DVModelEvents + * - DVModelChildren + * + * The purpose of exporting the DVModel classes + * is to make them available to the converter from + * JD's XML format and the expression parser. These + * components are expected to generate and update the + * DVModel. + * + * An application written by JS should only import + * DynamicView, DVModelContainer to be used in their own ArkUI + * container view. + */ + +/** + * View Model classes + */ + +@Observed +export class DVModelParameters extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelEvents extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelChildren extends Array { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +let nextId: number = 1; + +@Observed +export class DVModel { + id_: number; + compType: string; + params: DVModelParameters; + events: DVModelEvents; + children: DVModelChildren; + builder: ESObject; + + constructor(compType: string, params: DVModelParameters, events: DVModelEvents, children: DVModelChildren, builder?: ESObject) { + this.id_ = nextId++; + this.compType = compType; + this.params = params ?? new DVModelParameters; + this.events = events; + this.children = children; + this.builder = builder; + } + + public getLayoutParams(): DVModelParameters { + return this.params; + } +} + +// includes the root DVModel objects. +export class DVModelContainer { + model: DVModel; + + constructor(model: DVModel) { + this.model = model; + } +} + +/** + DynamicView is the @Component that does all the work: + + The following 4 features are the key solution elements for dynamic View + construction and update: + + 1. The if statement decides which framework component to create. + We can not use a factory function here, because that would requite calling + a regular function inside build() or a @Builder function. + + 2. Take note of the @Builder for Row, Column containers: + These functions create DynamicView Views inside a DynamicView + view. This behaviour is why we talk about DynamicView as a 'recursive' View. + All @Builder functions are member functions of the DynamicView @Component to + retain access ('this.xyz') to its decorated state variables. + + 3. The @Extend functions execute attribute and event handler registration functions + for all attributes and events permissable on the framework component, irrespective + if DVModelParameters or DVModelEvents objects includes a value or not. If not + the attribute or event is set to 'undefined' by intention. This is required to unset + any previously set value. + + 4. The scope ('this') of any lambda registered as an event hander function, e.g. for onClick, + is the @Component, in which the DVModel object is initialized. This said, it is advised to initialize + the DVModel object in the @Component that is parent to outmost DynamicView. Thereby, + any event handler function is able to mutate decorated state variables of that @Component + + */ + +@Component +export struct DynamicView { + @ObjectLink model: DVModel; + @ObjectLink children: DVModelChildren; + @ObjectLink params: DVModelParameters; + @ObjectLink events: DVModelEvents; + @BuilderParam customBuilder?: ($$: BuilderParams) => void; + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + getEvents: (events: DVModelEvents, element: string) => ESObject = (events: DVModelEvents, element: string): ESObject => { + let events2 = events as Record; + return events2.element; + } + + /* + we use this @Styles member function to set all common attributes and event handlers + and set component specific attribute and event handler functions in the @Builder function + */ + @Styles + common_attrs() { + // let params2 = this.params as Record | matrix4.Matrix4Transit>; + // .width(this.params["width"]) + // .height(this.params["height"]) + // .backgroundColor(this.params["backgroundColor"]) + // .onClick(this.events["onClick"]) + // .margin({ + // left: this.params["marginLeft"], + // right: this.params["marginRight"], + // top: this.params["marginTop"], + // bottom: this.params["marginBottom"] + // }) + // .onTouch(this.events["onTouch"]) + // .onFocus(this.events['onFocus']) + // .onBlur(this.events["onBlur"]) + // .translate({ + // x: this.params["translateX"], + // y: this.params["translateY"], + // z: this.params["translateZ"] + // }) + // .transform(this.params["matrix"]) + // .direction(this.params["direction"])this.getParams(this.params, "") + .width(this.getParams(this.params, "width")) + .height(this.getParams(this.params, "height")) + .backgroundColor(this.getParams(this.params, "backgroundColor")) + .onClick(this.getEvents(this.events, "onClick")) + .margin({ + left: this.getParams(this.params, "marginLeft"), + right: this.getParams(this.params, "marginRight"), + top: this.getParams(this.params, "marginTop"), + bottom: this.getParams(this.params, "marginBottom") + }) + .onTouch(this.getEvents(this.events, "onTouch")) + .onFocus(this.getEvents(this.events, "onFocus")) + .onBlur(this.getEvents(this.events, "onBlur")) + .translate({ + x: this.getParams(this.params, "translateX"), + y: this.getParams(this.params, "translateY"), + z: this.getParams(this.params, "translateZ") + }) + .transform(this.getParams(this.params, "matrix")) + .direction(this.getParams(this.params, "direction")) + } + + @Styles + clip_attrs() { + .clip(this.getParams(this.params, "rectWidth") ? new Rect({ + width: this.getParams(this.params, "rectWidth"), + height: this.getParams(this.params, "rectHeight"), + radius: this.getParams(this.params, "rectRadius") + }) : null) + .clip(this.getParams(this.params, "pathWidth") ? new Path({ + width: this.getParams(this.params, "pathWidth"), + height: this.getParams(this.params, "pathHeight"), + commands: this.getParams(this.params, "pathCommands") + }) : null) + } + + @Builder + buildChildren() { + ForEach(this.children, + (child: ESObject) => { + DynamicView({ + model: child as DVModel, + params: child.params, + events: child.events, + children: child.children, + customBuilder: child.builder + }) + }, + (child: ESObject) => `${child.id_}` + ) + } + + @Builder + buildRow() { + Row() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildColumn() { + Column() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildStack() { + Stack() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + .alignContent(this.getParams(this.params, "alignContent")) + } + + @Builder + buildText() { + Text(`${this.getParams(this.params, "value")}`) + .common_attrs() + .fontColor(this.getParams(this.params, "fontColor")) + } + + @Builder + buildImage() { + Image(this.getParams(this.params, "src")) + .common_attrs() + } + + // Button with label + @Builder + buildButton() { + Button(this.getParams(this.params, "value")) + .common_attrs() + } + + @Builder + buildCustom() { + if (this.customBuilder) { + this.customBuilder(new BuilderParams(this.params)); + } + } + + build() { + if (this.model.compType == "Column") { + this.buildColumn() + } else if (this.model.compType == "Row") { + this.buildRow() + } else if (this.model.compType == "Stack") { + this.buildStack() + } else if (this.model.compType == "Text") { + this.buildText() + } else if (this.model.compType == "Image") { + this.buildImage() + } else if (this.model.compType == "Button") { + this.buildButton() + } else { + this.buildCustom() + } + } +} + +export class BuilderParams { + params: DVModelParameters; + + constructor(params: DVModelParameters) { + this.params = params; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b97e5e5092748f7bc9e0f3af7482921891baf0f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DVModel, DVModelParameters, DVModelEvents, DVModelChildren } from "./dynamicView"; + +export function createDVModelFromJson(json: Object): DVModel { + + /* private use helper functions */ + let createChildrenFrom: (children: Array) => DVModelChildren = (children: Array): DVModelChildren => { + let result = new DVModelChildren(); + if (Array.isArray(children)) { + (children as Array).forEach(child => { + const childView = createDVModelFromJson(child); + if (childView != undefined) { + result.push(childView); + } + }); + } + return result; + } + + let setParams: (result: DVModelParameters | DVModelEvents, key: ESObject, element: Object ) => void = (result: DVModelParameters, key: ESObject, element: ESObject): void => { + let newResult = result as Record; + newResult.key = element.key; + } + + let createAttributesFrom: (attributes: Object) => DVModelParameters = (attributes: Object): DVModelParameters => { + let result = new DVModelParameters(); + if ((typeof attributes == "object") && (!Array.isArray(attributes))) { + Object.keys(attributes).forEach(k => {setParams(result, k, attributes)}); + } + return result; + } + + let createEventsFrom: (events: Object) => DVModelEvents = (events: Object): DVModelEvents => { + let result = new DVModelEvents(); + if ((typeof events == "object") && (!Array.isArray(events))) { + Object.keys(events).forEach(k => {setParams(result, k, events)}); + } + return result; + } + + if (typeof json !== 'object') { + console.error("createDVModelFromJson: input is not JSON"); + return undefined; + } + + let jsonObject = json as Record; + return new DVModel( + jsonObject.compType, + createAttributesFrom(jsonObject["attributes"]), + createEventsFrom(jsonObject["events"]), + createChildrenFrom(jsonObject["children"]), + jsonObject["build"] + ); +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..f52152001a497e70586215af090b2a81190e1187 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from '../embedding/engine/FlutterNapi'; + +export class FlutterCallbackInformation { + callbackName: string; + callbackClassName: string; + callbackLibraryPath: string; + + /** + * Get callback information for a given handle. + * + * @param handle the handle for the callback, generated by `PluginUtilities.getCallbackHandle` in + * `dart:ui`. + * @return an instance of FlutterCallbackInformation for the provided handle. + */ + static lookupCallbackInformation(handle: number): FlutterCallbackInformation { + return FlutterNapi.nativeLookupCallbackInformation(handle); + } + + constructor(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { + this.callbackName = callbackName; + this.callbackClassName = callbackClassName; + this.callbackLibraryPath = callbackLibraryPath; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets new file mode 100644 index 0000000000000000000000000000000000000000..6cc452fb32b855832651463166ae1a7f8cf5f0d4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets @@ -0,0 +1,122 @@ +import common from '@ohos.app.ability.common'; +import DartExecutor from '../embedding/engine/dart/DartExecutor'; +import { EngineLifecycleListener } from '../embedding/engine/FlutterEngine'; +import FlutterNapi from '../embedding/engine/FlutterNapi'; +import Log from '../util/Log'; +import FlutterPluginRegistry from '../app/FlutterPluginRegistry'; +import FlutterRunArguments from './FlutterRunArguments'; +import { FlutterView } from './FlutterView'; + +const TAG: string = "FlutterNativeView"; + +export default class FlutterNativeView { + private mContext: common.Context; + private mPluginRegistry: FlutterPluginRegistry; + private mFlutterNapi: FlutterNapi; + private dartExecutor: DartExecutor; + private mFlutterView: FlutterView; + private applicationIsRunning: boolean; + + constructor(context: common.Context, isBackgroundView?: boolean) { + if (isBackgroundView) { + Log.i(TAG, "isBackgroundView is no longer supported and will be ignored"); + } + this.mContext = context; + this.mPluginRegistry = new FlutterPluginRegistry(); + this.mFlutterNapi = new FlutterNapi(); + //this.mFlutterNapi.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.dartExecutor = new DartExecutor(this.mFlutterNapi, this.mContext.resourceManager); + this.mFlutterNapi.addEngineLifecycleListener(new EngineLifecycleListenerImpl(this.mFlutterView, this.mPluginRegistry)); + this.attach(this.mFlutterNapi, this.dartExecutor); + this.assertAttached(this.mFlutterNapi); + } + + attach(flutterNapi: FlutterNapi, dartExecutor: DartExecutor): void { + flutterNapi.attachToNative(); + dartExecutor.onAttachedToNAPI(); + } + + assertAttached(flutterNapi: FlutterNapi): void { + if (!this.isAttached(flutterNapi)) { + throw new Error('Platform View is not attached'); + } + } + + isAttached(flutterNapi: FlutterNapi): boolean { + return flutterNapi.isAttached(); + } + + detachFromFlutterView(): void { + this.mPluginRegistry.detach(); + this.mFlutterView = null; + } + + destroy(): void { + this.mPluginRegistry.destroy(); + this.dartExecutor.onDetachedFromNAPI(); + this.mFlutterView = null; + //this.mFlutterNapi.removeIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.applicationIsRunning = false; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor; + } + + getPluginRegistry(): FlutterPluginRegistry { + return this.mPluginRegistry; + } + + attachViewAndAbility(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mPluginRegistry.attach(flutterView, context); + } + + runFromBundle(args: FlutterRunArguments): void { + if (args.entrypoint == null) { + throw new Error("an entrypoint must be specific"); + } + this.assertAttached(this.mFlutterNapi); + if (this.applicationIsRunning) { + throw new Error("this flutter engine instance is already running an application"); + } + this.mFlutterNapi.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.resourceManager, null); + this.applicationIsRunning = true; + } + + isApplicationRunning(): boolean { + return this.applicationIsRunning; + } + + // getObservatoryUri(): string { + // return this.mFlutterNapi.getObservatoryUri(); + // } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private flutterView: FlutterView; + private pluginRegistry: FlutterPluginRegistry; + + onPreEngineRestart(): void { + if (this.flutterView != null) { + //this.flutterView.resetAccessibilityTree(); + } + + if (this.pluginRegistry == null) { + return; + } + + this.pluginRegistry.onPreEngineRestart(); + } + + onEngineWillDestroy(): void { + + } + + constructor(flutterView: FlutterView, pluginRegistry: FlutterPluginRegistry) { + this.flutterView = flutterView; + this.pluginRegistry = pluginRegistry; + } +} + + diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets new file mode 100644 index 0000000000000000000000000000000000000000..6354ecc36f87206b30a3a247612e103559356137 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets @@ -0,0 +1,5 @@ +export default class FlutterRunArguments { + public bundlePath: string; + public entrypoint: string; + public libraryPath: string; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f940a6c57576a7123b70531b0880f6ba31d29e2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets @@ -0,0 +1,3 @@ +export class FlutterView { + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b73c7401b711eb78028ae6f91ae3e5e40d2a418 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets @@ -0,0 +1,22 @@ + +export interface TextureRegistry { + + createSurfaceTexture(): SurfaceTextureEntry; + registerSurfaceTexture(): SurfaceTextureEntry; + + onTrimMemory(level: number) : void; +} + +interface SurfaceTextureEntry { + id(): number; + + release(): void; +} + +interface OnFrameConsumedListener { + onFrameConsumed(): void; +} + +interface OnTrimMemoryListener { + onTrimMemory(level: number) : void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..7fa2db04597c775a12de37f1581fec38009a0127 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json @@ -0,0 +1,20 @@ +{ + "app": { + "bundleName": "net.openvalley.helloworld", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "flutter_embedding", + "type": "har", + "deviceTypes": [ + "default" + ] + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159750ecea7bec636e067dea44f6b469601d685 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x02000000 \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..95e376706d75437dce67c79dfd886e97fa82f276 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + } + ], +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c96b70703b57d3e53a171aabf07727db248e94b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export { FlutterAbility } from './src/main/ets/embedding/ohos/FlutterAbility' + +export { FlutterPage } from './src/main/ets/embedding/ohos/FlutterPage' diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..48de9bfe141e9caa2a264e5d10b485cf28043e10 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "Apache-2.0", + "devDependencies": { + "@types/libflutter.so": "file:./src/main/cpp/types/libflutter" + }, + "author": "", + "name": "flutter_embedding", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f95808136a13ece2a5946e0aa6ff97e2a5eadb --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import image from '@ohos.multimedia.image'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; + +export const getContext: (a: number) => napiContext; + +export class napiContext { + onPageShow(); + + onPageHide(); +} + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => {}; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + +export const nativeAttach: (napi: FlutterNapi) => number; + +export const nativeRunBundleAndSnapshotFromLibrary: ( + nativeShellHolderId: number, + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +//Send a data-carrying response to a platform message received from Dart. +export const nativeInvokePlatformMessageResponseCallback: (nativeShellHolderId: number, responseId: number, message: ArrayBuffer, position: number) => void; + +// Send an empty response to a platform message received from Dart. +export const nativeInvokePlatformMessageEmptyResponseCallback: (nativeShellHolderId: number, responseId: number) => void; + +// Send a data-carrying platform message to Dart. +export const nativeDispatchPlatformMessage: (nativeShellHolderId: number, channel: String, message: ArrayBuffer, position: number, responseId: number) => void; + +// Send an empty platform message to Dart. +export const nativeDispatchEmptyPlatformMessage: (nativeShellHolderId: number, channel: String, responseId: number) => void; + +export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array) => void; + +export const nativeImageDecodeCallback: (width: number, height: number, imageGeneratorPointer: number, pixelMap : image.PixelMap) => void; + +export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f74af44a9d9f5796d76516723d45ec0a8791a76b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts @@ -0,0 +1,267 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import image from '@ohos.multimedia.image'; + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => void; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + + +/** + * 加载dart工程构建产物 + */ +export const nativeRunBundleAndSnapshotFromLibrary: ( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +/** + * 初始化SkFontMgr::RefDefault(),skia引擎文字管理初始化 + */ +export const nativePrefetchDefaultFontManager: () => void; + +/** + * 返回是否支持软件绘制 + */ +export const nativeGetIsSoftwareRenderingEnabled: () => boolean; + +/** + * attach flutterNapi实例给到 native engine,这个支持rkts到flutter平台的无关引擎之间的通信。 + * attach只需要执行一次 + */ +export const nativeAttach: (flutterNapi: FlutterNapi) => number; + +/** + * 从当前的flutterNapi复制一个新的实例 + */ +export const nativeSpawn: ( + nativeSpawningShellId: number, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + initialRoute: string, + entrypointArgs: Array +) => FlutterNapi; + +/** + * Detaches flutterNapi和engine之间的关联 + * 这个方法执行前提是flutterNapi已经和engine关联 + */ +export const nativeDestroy: ( + nativeShellHolderId: number +) => void; + +// 不需要实现,未使用到 +// export const nativeImageHeaderCallback: ( +// imageGeneratorPointer: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceCreated: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceWindowChanged: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceChanged: ( +// nativeShellHolderId: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceDestroyed: ( +// nativeShellHolderId: number +// ) => void; + +/** + * 把物理屏幕参数通知到native + */ +export const nativeSetViewportMetrics: ( + nativeShellHolderId: number, + devicePixelRatio: number, + physicalWidth: number, + physicalHeight: number, + physicalPaddingTop: number, + physicalPaddingRight: number, + physicalPaddingBottom: number, + physicalPaddingLeft: number, + physicalViewInsetTop: number, + physicalViewInsetRight: number, + physicalViewInsetBottom: number, + physicalViewInsetLeft: number, + systemGestureInsetTop: number, + systemGestureInsetRight: number, + systemGestureInsetBottom: number, + systemGestureInsetLeft: number, + physicalTouchSlop: number, + displayFeaturesBounds: Array, + displayFeaturesType: Array, + displayFeaturesState: Array +) => void; + +/** + * 设置能力参数 + */ +export const nativeSetAccessibilityFeatures: ( + nativeShellHolderId: number, + flags: number +) => void; + +/** + * 清除某个messageData + */ +export const nativeCleanupMessageData: ( + messageData: number +) => void; + +/** + * 发送一个空的PlatformMessage + */ +export const nativeDispatchEmptyPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + responseId: number +) => void; + +/** + * 发送一个PlatformMessage + */ +export const nativeDispatchPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + message: ArrayBuffer, + position: number, + responseId: number +) => void; + +/** + * 空的PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageEmptyResponseCallback: ( + nativeShellHolderId: number, + responseId: number +) => void; + +/** + * PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageResponseCallback: ( + nativeShellHolderId: number, + responseId: number, + message: ArrayBuffer, + position: number +) => void; + + +/** + * load一个合法的.so文件到dart vm + */ +export const nativeLoadDartDeferredLibrary: ( + nativeShellHolderId: number, + loadingUnitId: number, + searchPaths: Array +) => void; + +/** + * 设置ResourceManager和assetBundlePath到engine + */ +export const nativeUpdateOhosAssetManager: ( + nativeShellHolderId: number, + resourceManager: resourceManager.ResourceManager, + assetBundlePath: string +) => void; + +/** + * 加载动态库,或者dart库失败时的通知 + */ +export const nativeDeferredComponentInstallFailure: ( + loadingUnitId: number, + error: string, + isTransient: boolean +) => void; + +/** + * 从engine获取当前绘制pixelMap + */ +export const nativeGetPixelMap: () => image.PixelMap; + +/** + * 应用低内存警告 + */ +export const nativeNotifyLowMemoryWarning: ( + nativeShellHolderId: number +) => void; + +// ----- Start FlutterTextUtils Methods ---- +/** + * 下面的方法,从键盘输入中判断当前字符是否是emoji,实现优先级低 + */ +export const nativeFlutterTextUtilsIsEmoji: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifier: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifierBase: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsVariationSelector: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsRegionalIndicator: ( + codePoint: number +) => boolean; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..216ed0d7205d22e5524249550749945324d041bc --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "name": "libflutter.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6f2f8b0e5dd765611d87ac3b2c2c552ff5adb2 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from './embedding/engine/FlutterNapi'; +import FlutterLoader from './embedding/engine/loader/FlutterLoader'; + +/** + * flutter相关主要类的单例持有,帮助实现自身和其他类的实例化管理 + */ +export default class FlutterInjector { + private static instance: FlutterInjector; + + private flutterLoader: FlutterLoader; + private flutterNapi: FlutterNapi; + + static getInstance(): FlutterInjector { + if (FlutterInjector.instance == null) { + FlutterInjector.instance = new FlutterInjector(); + } + return FlutterInjector.instance; + } + /** + * 初始化 + */ + private constructor() { + this.flutterNapi = new FlutterNapi(); + this.flutterLoader = new FlutterLoader(this.flutterNapi); + } + + getFlutterLoader(): FlutterLoader { + return this.flutterLoader; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..20e2d2086540ce12a257899f05386ac9076842cf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + import FlutterView from '../embedding/ohos/FlutterView'; +import common from '@ohos.app.ability.common'; +import PlatformViewController from '../plugin/platform/PlatformViewsController' +import Log from '../util/Log'; + +export default class FlutterPluginRegistry { + private mPlatformViewsController: PlatformViewController; + private mFlutterView: FlutterView; + private mContext: common.Context; + + constructor() { + this.mPlatformViewsController = new PlatformViewController(); + } + + attach(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mContext = context; + } + + detach(): void { + this.mPlatformViewsController.detach(); + this.mPlatformViewsController.onDetachedFromNapi(); + this.mFlutterView = null; + this.mContext = null; + } + + destroy(): void { + this.mPlatformViewsController.onDetachedFromNapi(); + } + + onPreEngineRestart(): void{ + this.mPlatformViewsController.onPreEngineRestart(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..07497e672b21c51727c1a45166504e19603e4063 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * 基础component,还未封装,看情况是否使用 + */ +@Component +export default struct FlutterComponent { + build() { + Row() { + Column() { + Text("xxx") + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a16a419d9c7a5df84379278cdc7fb113624d7f7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets @@ -0,0 +1,277 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LifecycleChannel from './systemchannels/LifecycleChannel'; +import DartExecutor, { DartEntrypoint } from './dart/DartExecutor'; +import FlutterShellArgs from './FlutterShellArgs'; +import FlutterInjector from '../../FlutterInjector'; +import FlutterLoader from './loader/FlutterLoader'; +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from './FlutterNapi'; +import NavigationChannel from './systemchannels/NavigationChannel'; +import Log from '../../util/Log'; +import TestChannel from './systemchannels/TestChannel' +import FlutterEngineConnectionRegistry from './FlutterEngineConnectionRegistry'; +import PluginRegistry from './plugins/PluginRegistry'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import TextInputChannel from './systemchannels/TextInputChannel'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import PlatformChannel from './systemchannels/PlatformChannel'; +import FlutterEngineGroup from './FlutterEngineGroup'; +import SystemChannel from './systemchannels/SystemChannel'; +import MouseCursorChannel from './systemchannels/MouseCursorChannel'; +import RestorationChannel from './systemchannels/RestorationChannel'; +import LocalizationChannel from './systemchannels/LocalizationChannel'; +import AccessibilityChannel from './systemchannels/AccessibilityChannel'; +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' +import SettingsChannel from './systemchannels/SettingsChannel'; +import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; + +const TAG = "FlutterEngine"; + +/** + * 操作FlutterEngin相关 + */ +export default class FlutterEngine implements EngineLifecycleListener{ + private engineLifecycleListeners = new Set(); + + dartExecutor: DartExecutor; + private flutterLoader: FlutterLoader; + private assetManager: resourceManager.ResourceManager; + //channel定义 + private lifecycleChannel: LifecycleChannel; + private navigationChannel: NavigationChannel; + private textInputChannel: TextInputChannel; + private testChannel: TestChannel; + private platformChannel: PlatformChannel; + private systemChannel: SystemChannel; + private mouseCursorChannel: MouseCursorChannel; + private restorationChannel: RestorationChannel; + + private accessibilityChannel: AccessibilityChannel; + private localeChannel: LocalizationChannel; + private flutterNapi: FlutterNapi; + private pluginRegistry: FlutterEngineConnectionRegistry; + private textInputPlugin: TextInputPlugin; + private localizationPlugin: LocalizationPlugin; + private settingsChannel: SettingsChannel; + private platformViewsController: PlatformViewsController; + + /** + * 需要初始化的工作: + * 1、初始化DartExecutor + * 2、初始化所有channel + * 3、初始化plugin + * 4、初始化flutterLoader + * 5、初始化flutterNapi + * 6、engineLifecycleListeners + */ + constructor(context: common.Context, flutterLoader: FlutterLoader, flutterNapi: FlutterNapi, platformViewsController: PlatformViewsController) { + const injector: FlutterInjector = FlutterInjector.getInstance(); + + if(flutterNapi == null){ + flutterNapi = FlutterInjector.getInstance().getFlutterNapi(); + } + this.flutterNapi = flutterNapi; + this.assetManager = context.resourceManager; + + this.dartExecutor = new DartExecutor(this.flutterNapi, this.assetManager); + this.dartExecutor.onAttachedToNAPI(); + + if(flutterLoader == null){ + flutterLoader = injector.getFlutterLoader(); + } + this.flutterLoader = flutterLoader; + + if(platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + this.platformViewsController = platformViewsController; + this.platformViewsController.attach(context, null, this.dartExecutor); + } + + async init(context: common.Context, dartVmArgs: Array, automaticallyRegisterPlugins: boolean, + waitForRestorationData: boolean, group: FlutterEngineGroup) { + if (!this.flutterNapi.isAttached()) { + await this.flutterLoader.startInitialization(context) + this.flutterLoader.ensureInitializationComplete(dartVmArgs); + } + //channel初始化 + this.lifecycleChannel = new LifecycleChannel(this.dartExecutor); + this.navigationChannel = new NavigationChannel(this.dartExecutor); + this.textInputChannel = new TextInputChannel(this.dartExecutor); + this.testChannel = new TestChannel(this.dartExecutor); + this.platformChannel = new PlatformChannel(this.dartExecutor); + this.systemChannel = new SystemChannel(this.dartExecutor); + this.mouseCursorChannel = new MouseCursorChannel(this.dartExecutor); + this.restorationChannel = new RestorationChannel(this.dartExecutor, waitForRestorationData); + this.settingsChannel = new SettingsChannel(this.dartExecutor); + + this.localeChannel = new LocalizationChannel(this.dartExecutor); + this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); + this.flutterNapi.addEngineLifecycleListener(this); + this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); + + // It should typically be a fresh, unattached NAPI. But on a spawned engine, the NAPI instance + // is already attached to a native shell. In that case, the Java FlutterEngine is created around + // an existing shell. + if (!this.flutterNapi.isAttached()) { + this.attachToNapi(); + } + + this.pluginRegistry = new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, this.flutterLoader, group); + this.localizationPlugin.sendLocaleToFlutter(); + } + + private attachToNapi(): void { + Log.d(TAG, "Attaching to NAPI."); + this.flutterNapi.attachToNative(); + + if (!this.isAttachedToNapi()) { + throw new Error("FlutterEngine failed to attach to its native Object reference."); + } + this.flutterNapi.setLocalizationPlugin(this.localizationPlugin); + } + + async spawn(context: common.Context, + dartEntrypoint: DartEntrypoint, + initialRoute: string, + dartEntrypointArgs: Array, + platformViewsController: PlatformViewsController, + automaticallyRegisterPlugins: boolean, waitForRestorationData: boolean) { + if (!this.isAttachedToNapi()) { + throw new Error( + "Spawn can only be called on a fully constructed FlutterEngine"); + } + + const newFlutterNapi = + this.flutterNapi.spawn( + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + initialRoute, + dartEntrypointArgs); + const flutterEngine = new FlutterEngine( + context, + null, + newFlutterNapi, + platformViewsController + ); + await flutterEngine.init(context, null, automaticallyRegisterPlugins, waitForRestorationData, null) + return flutterEngine + } + + private isAttachedToNapi(): boolean { + return this.flutterNapi.isAttached(); + } + + getLifecycleChannel(): LifecycleChannel { + return this.lifecycleChannel; + } + + getNavigationChannel(): NavigationChannel { + return this.navigationChannel; + } + + getTextInputChannel(): TextInputChannel { + return this.textInputChannel; + } + + getPlatformChannel(): PlatformChannel { + return this.platformChannel; + } + + getSystemChannel(): SystemChannel { + return this.systemChannel; + } + + getLocaleChannel(): LocalizationChannel { + return this.localeChannel; + } + + getMouseCursorChannel(): MouseCursorChannel { + return this.mouseCursorChannel; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor + } + + getPlugins(): PluginRegistry { + return this.pluginRegistry; + } + + getAbilityControlSurface(): AbilityControlSurface { + return this.pluginRegistry; + } + + getSettingsChannel() { + return this.settingsChannel; + } + + onPreEngineRestart(): void { + + } + + onEngineWillDestroy(): void { + + } + + addEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(listener); + } + + removeEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.delete(listener); + } + + destroy(): void { + Log.d(TAG, "Destroying."); + this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) + this.flutterNapi.removeEngineLifecycleListener(this); + this.pluginRegistry.detachFromAbility(); + this.platformViewsController.onDetachedFromNapi(); + } + + getRestorationChannel(): RestorationChannel{ + return this.restorationChannel; + } + + getAccessibilityChannel(): AccessibilityChannel { + return this.accessibilityChannel; + } + + getLocalizationPlugin(): LocalizationPlugin { + return this.localizationPlugin; + } + + getSystemLanguages(): void { + return this.flutterNapi.getSystemLanguages(); + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } +} + +export interface EngineLifecycleListener { + onPreEngineRestart(): void; + + onEngineWillDestroy(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..78db31cae3a9d154a09f9f85541115dc4452573f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from "./FlutterEngine" + +export default class FlutterEngineCache { + private static instance : FlutterEngineCache; + private cachedEngines: Map = new Map(); + + static getInstance(): FlutterEngineCache { + if (FlutterEngineCache.instance == null) { + FlutterEngineCache.instance = new FlutterEngineCache(); + } + return FlutterEngineCache.instance; + } + /** + * 返回engineId对应的FlutterEngine是否存在 + */ + contains(engineId: String) : boolean { + return this.cachedEngines.has(engineId); + } + + /** + * 返回engineId对应的FlutterEngine + */ + get(engineId: String) : FlutterEngine { + return this.cachedEngines.get(engineId); + } + /** + * 将传入的FlutterEngine与engineId放在缓存中 + */ + put(engineId :String, engine: FlutterEngine): void { + if(engine != null) { + this.cachedEngines.set(engineId, engine); + } else { + this.cachedEngines.delete(engineId); + } + } + /** + * 移除engineId对应的FlutterEngine + */ + remove(engineId: String) : void { + this.put(engineId, null); + } + + /** + * 移除cachedEngines所有中所有的FlutterEngine + */ + clear():void { + this.cachedEngines.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..7709ea8a31e98f794314a7e2f3b84e890f1eee9f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PluginRegistry from './plugins/PluginRegistry'; +import { FlutterAssets, FlutterPlugin, FlutterPluginBinding } from './plugins/FlutterPlugin'; +import FlutterEngine from './FlutterEngine'; +import AbilityAware from './plugins/ability/AbilityAware'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import { + AbilityPluginBinding, + WindowFocusChangedListener, + OnSaveStateListener, + NewWantListener +} from './plugins/ability/AbilityPluginBinding'; +import HashSet from '@ohos.util.HashSet'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import common from '@ohos.app.ability.common'; +import FlutterLoader from './loader/FlutterLoader'; +import Log from '../../util/Log'; +import ToolUtils from '../../util/ToolUtils'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import ExclusiveAppComponent from '../ohos/ExclusiveAppComponent'; +import FlutterEngineGroup from './FlutterEngineGroup'; + +const TAG = "FlutterEngineCxnRegstry"; + +export default class FlutterEngineConnectionRegistry implements PluginRegistry, AbilityControlSurface { + // PluginRegistry + private plugins = new Map(); + + // Standard FlutterPlugin + private flutterEngine: FlutterEngine; + private pluginBinding: FlutterPluginBinding; + + // AbilityAware + private abilityAwarePlugins = new Map(); + + private exclusiveAbility: ExclusiveAppComponent; + private abilityPluginBinding: FlutterEngineAbilityPluginBinding; + + constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader, group: FlutterEngineGroup) { + this.flutterEngine = flutterEngine; + this.pluginBinding = new FlutterPluginBinding(appContext, this.flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), group, this.flutterEngine.getPlatformViewsController()?.getRegistry()); + } + + add(plugin: FlutterPlugin): void { + try { + if (this.has(plugin.getUniqueClassName())) { + Log.w( + TAG, + "Attempted to register plugin (" + + plugin + + ") but it was " + + "already registered with this FlutterEngine (" + + this.flutterEngine + + ")."); + return; + } + + Log.w(TAG, "Adding plugin: " + plugin); + // Add the plugin to our generic set of plugins and notify the plugin + // that is has been attached to an engine. + this.plugins.set(plugin.getUniqueClassName(), plugin); + plugin.onAttachedToEngine(this.pluginBinding); + + // For AbilityAware plugins, add the plugin to our set of AbilityAware + // plugins, and if this engine is currently attached to an Ability, + // notify the AbilityAware plugin that it is now attached to an Ability. + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + const abilityAware: ESObject = plugin; + this.abilityAwarePlugins.set(plugin.getUniqueClassName(), abilityAware); + if (this.isAttachedToAbility()) { + abilityAware.onAttachedToAbility(this.abilityPluginBinding); + } + } + } finally { + + } + } + + addList(plugins: Set): void { + plugins.forEach(plugin => this.add(plugin)) + } + + has(pluginClassName: string): boolean { + return this.plugins.has(pluginClassName); + } + + get(pluginClassName: string): FlutterPlugin { + return this.plugins.get(pluginClassName); + } + + remove(pluginClassName: string): void { + const plugin = this.plugins.get(pluginClassName); + if (plugin == null) { + return; + } + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + if (this.isAttachedToAbility()) { + const abilityAware: ESObject = plugin; + abilityAware.onDetachedFromAbility(); + } + this.abilityAwarePlugins.delete(pluginClassName); + } + // Notify the plugin that is now detached from this engine. Then remove + // it from our set of generic plugins. + plugin.onDetachedFromEngine(this.pluginBinding); + this.plugins.delete(pluginClassName) + } + + removeList(pluginClassNames: Set): void { + pluginClassNames.forEach(plugin => this.remove(plugin)) + } + + removeAll(): void { + this.removeList(new Set(this.plugins.keys())); + this.plugins.clear(); + } + + private isAttachedToAbility(): boolean { + return this.exclusiveAbility != null; + } + + attachToAbility(exclusiveAbility: ExclusiveAppComponent): void { + if (this.exclusiveAbility != null) { + this.exclusiveAbility.detachFromFlutterEngine(); + } + // If we were already attached to an app component, detach from it. + this.detachFromAppComponent(); + this.exclusiveAbility = exclusiveAbility; + this.attachToAbilityInternal(exclusiveAbility.getAppComponent(),); + } + + detachFromAbility(): void { + if (this.isAttachedToAbility()) { + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onDetachedFromAbility()) + this.detachFromAbilityInternal(); + } else { + Log.e(TAG, "Attempted to detach plugins from an Ability when no Ability was attached."); + } + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.abilityPluginBinding.onNewWant(want, launchParams); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.abilityPluginBinding.onWindowFocusChanged(hasFocus); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + return this.abilityPluginBinding.onSaveState(reason, wantParam); + } + + private detachFromAppComponent(): void { + if (this.isAttachedToAbility()) { + this.detachFromAbility(); + } + } + + private attachToAbilityInternal(ability: UIAbility): void { + this.abilityPluginBinding = new FlutterEngineAbilityPluginBinding(ability); + // Notify all AbilityAware plugins that they are now attached to a new Ability. + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onAttachedToAbility(this.abilityPluginBinding)); + } + + private detachFromAbilityInternal(): void { + this.exclusiveAbility = null; + this.abilityPluginBinding = null; + } + + destroy(): void{ + this.detachFromAppComponent(); + // Remove all registered plugins. + this.removeAll(); + } +} + +class FlutterEngineAbilityPluginBinding implements AbilityPluginBinding { + private ability: UIAbility; + private onNewWantListeners = new HashSet(); + private onWindowFocusChangedListeners = new HashSet(); + private onSaveStateListeners = new HashSet(); + + constructor(ability: UIAbility) { + this.ability = ability; + + } + + getAbility(): UIAbility { + return this.ability; + } + + addOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.add(listener) + } + + removeOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.remove(listener) + } + + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.add(listener) + } + + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.remove(listener) + } + + addOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.add(listener) + } + + removeOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.remove(listener) + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.onNewWantListeners.forEach((listener, key) => { + listener.onNewWant(want, launchParams) + }); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.onWindowFocusChangedListeners.forEach((listener, key) => { + listener.onWindowFocusChanged(hasFocus) + }); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + this.onSaveStateListeners.forEach((listener, key) => { + listener.onSaveState(reason, wantParam) + }); + return AbilityConstant.OnSaveResult.ALL_AGREE; + } +} + +class DefaultFlutterAssets implements FlutterAssets { + private flutterLoader: FlutterLoader; + + constructor(flutterLoader: FlutterLoader) { + this.flutterLoader = flutterLoader; + } + + getAssetFilePathByName(assetFileName: string, packageName?: string): string { + return this.flutterLoader.getLookupKeyForAsset(assetFileName, packageName); + } + + getAssetFilePathBySubpath(assetSubpath: string, packageName?: string) { + return this.flutterLoader.getLookupKeyForAsset(assetSubpath, packageName); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets new file mode 100644 index 0000000000000000000000000000000000000000..05e35aec1b7b6f50ab8df336bdd69fbbe21febc8 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" +import common from '@ohos.app.ability.common' +import FlutterLoader from './loader/FlutterLoader' +import FlutterInjector from '../../FlutterInjector' +import { DartEntrypoint } from './dart/DartExecutor' +import PlatformViewsController from '../../plugin/platform/PlatformViewsController' +import ArrayList from '@ohos.util.ArrayList' + +export default class FlutterEngineGroup { + private activeEngines: ArrayList = new ArrayList(); + + constructor() { + + } + + async checkLoader(context: common.Context, args: Array) { + let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!loader.initialized) { + await loader.startInitialization(context.getApplicationContext()); + loader.ensureInitializationComplete(args); + } + } + + async createAndRunEngineByOptions(options: Options) { + let engine: FlutterEngine = null; + let context: common.Context = options.getContext(); + let dartEntrypoint: DartEntrypoint = options.getDartEntrypoint(); + let initialRoute: string = options.getInitialRoute(); + let dartEntrypointArgs: Array = options.getDartEntrypointArgs(); + let platformViewsController: PlatformViewsController = options.getPlatformViewsController(); + let automaticallyRegisterPlugins: boolean = options.getAutomaticallyRegisterPlugins(); + let waitForRestorationData: boolean = options.getWaitForRestorationData(); + + if (dartEntrypoint == null) { + dartEntrypoint = DartEntrypoint.createDefault(); + } + + if (platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + + if (this.activeEngines.length == 0) { + engine = this.createEngine(context, platformViewsController); + await engine.init(context, null, // String[]. The Dart VM has already started, this arguments will have no effect. + automaticallyRegisterPlugins, // boolean. + waitForRestorationData, // boolean. + this) + if (initialRoute != null) { + engine.getNavigationChannel().setInitialRoute(initialRoute); + } + } else { + engine = await this.activeEngines[0] + .spawn( + context, + dartEntrypoint, + initialRoute, + dartEntrypointArgs, + platformViewsController, + automaticallyRegisterPlugins, + waitForRestorationData); + } + this.activeEngines.add(engine); + + const engineToCleanUpOnDestroy = engine; + let listener: EngineLifecycleListener = new EngineLifecycleListenerImpl( + platformViewsController, + this.activeEngines, + engineToCleanUpOnDestroy); + engine.addEngineLifecycleListener(listener); + return engine; + } + + createEngine(context: common.Context, platformViewsController: PlatformViewsController): FlutterEngine { + return new FlutterEngine(context, null, null, platformViewsController); + } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private platformViewsController: PlatformViewsController; + private activeEngines: ArrayList = new ArrayList(); + private engine: FlutterEngine; + + constructor( + platformViewsController: PlatformViewsController, + activeEngines: ArrayList, + engine: FlutterEngine) { + this.platformViewsController = platformViewsController; + this.activeEngines = activeEngines; + this.engine = engine; + } + onPreEngineRestart(): void { + this.platformViewsController.onPreEngineRestart(); + } + onEngineWillDestroy(): void { + this.activeEngines.remove(this.engine); + } +} + +export class Options { + private context: common.Context; + private dartEntrypoint: DartEntrypoint; + private initialRoute: string; + private dartEntrypointArgs: Array; + private platformViewsController: PlatformViewsController; + private automaticallyRegisterPlugins: boolean = true; + private waitForRestorationData: boolean = false; + + constructor(context: common.Context) { + this.context = context; + } + + getContext(): common.Context { + return this.context; + } + + getDartEntrypoint(): DartEntrypoint { + return this.dartEntrypoint; + } + + getInitialRoute(): string { + return this.initialRoute; + } + + getDartEntrypointArgs(): Array { + return this.dartEntrypointArgs; + } + + getAutomaticallyRegisterPlugins(): boolean { + return this.automaticallyRegisterPlugins; + } + + getWaitForRestorationData(): boolean { + return this.waitForRestorationData; + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } + + setDartEntrypoint(dartEntrypoint: DartEntrypoint): Options { + this.dartEntrypoint = dartEntrypoint; + return this; + } + + setInitialRoute(initialRoute: string): Options { + this.initialRoute = initialRoute; + return this; + } + + setDartEntrypointArgs(dartEntrypointArgs: Array): Options { + this.dartEntrypointArgs = dartEntrypointArgs; + return this; + } + + setAutomaticallyRegisterPlugins(automaticallyRegisterPlugins: boolean): Options { + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + return this; + } + + setWaitForRestorationData(waitForRestorationData: boolean): Options { + this.waitForRestorationData = waitForRestorationData; + return this; + } + + setPlatformViewsController(platformViewsController: PlatformViewsController): Options { + this.platformViewsController = platformViewsController; + return this; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b251069ce950ee8a0fb3d2f08b723a2d1e6f78 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngineGroup from './FlutterEngineGroup'; + +export default class FlutterEngineGroupCache { + static readonly instance = new FlutterEngineGroupCache(); + + private cachedEngineGroups = new Map(); + + contains(engineGroupId: string): boolean { + return this.cachedEngineGroups.has(engineGroupId); + } + + get(engineGroupId: string): FlutterEngineGroup { + return this.cachedEngineGroups.get(engineGroupId); + } + + put(engineGroupId: string, engineGroup?: FlutterEngineGroup) { + if (engineGroup != null) { + this.cachedEngineGroups.set(engineGroupId, engineGroup); + } else { + this.cachedEngineGroups.delete(engineGroupId); + } + } + + clear(): void { + this.cachedEngineGroups.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets new file mode 100644 index 0000000000000000000000000000000000000000..902699e44c585b355df699b78cca69b58f021055 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import flutter from 'libflutter.so'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log'; +import resourceManager from '@ohos.resourceManager'; +import { PlatformMessageHandler } from './dart/PlatformMessageHandler'; +import { FlutterCallbackInformation } from '../../view/FlutterCallbackInformation'; +import image from '@ohos.multimedia.image'; +import { EngineLifecycleListener } from './FlutterEngine'; +import { ByteBuffer } from '../../util/ByteBuffer'; +import { Action } from '../../view/AccessibilityBridge' +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin'; +import i18n from '@ohos.i18n'; + +const TAG = "FlutterNapi"; + +enum ContextType { + APP_LIFECYCLE = 0, + JS_PAGE_LIFECYCLE, +} + +/** + * 提供arkTs的flutterNAPI接口 + */ +export default class FlutterNapi { + hasInit: boolean = false; + //是否已实现 + hasImplemented: boolean = false; + + nativeShellHolderId: number = null; + platformMessageHandler: PlatformMessageHandler; + private engineLifecycleListeners = new Set(); + accessibilityDelegate: AccessibilityDelegate; + localizationPlugin: LocalizationPlugin; + + /** + * 更新刷新率 + * @param rate + */ + updateRefreshRate(refreshRateFPS : number) { + flutter.nativeUpdateRefreshRate(refreshRateFPS); + } + + init(context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number) { + if (this.hasInit) { + throw Error("the engine has init"); + } + this.hasInit = true; + Log.w(TAG, "init: bundlePath=" + bundlePath + " appStoragePath=" + appStoragePath + " engineCachesPath=" + engineCachesPath + " args=" + JSON.stringify(args)); + flutter.nativeInit(context, args, bundlePath, appStoragePath, engineCachesPath, initTimeMillis); + } + + attachToNative(): void { + this.nativeShellHolderId = flutter.nativeAttach(this); + Log.w(TAG, "nativeShellHolderId=" + this.nativeShellHolderId); + } + + runBundleAndSnapshotFromLibrary( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array) { + Log.w(TAG, "init: bundlePath=" + bundlePath + " entrypointFunctionName=" + entrypointFunctionName + " pathToEntrypointFunction=" + pathToEntrypointFunction + " entrypointArgs=" + JSON.stringify(entrypointArgs)) + flutter.nativeRunBundleAndSnapshotFromLibrary(this.nativeShellHolderId, bundlePath, entrypointFunctionName, pathToEntrypointFunction, assetManager, entrypointArgs); + }; + + /** + * 当前so方法是否都实现 + * @returns + */ + checkImplemented(methodName: string = ""): boolean { + if (!this.hasImplemented) { + Log.e(TAG, "this method has not implemented -> " + methodName) + } + return this.hasImplemented; + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.ensureRunningOnMainThread(); + this.platformMessageHandler = platformMessageHandler; + } + + private ensureAttachedToNative(): void { + if (this.nativeShellHolderId == null) { + throw new Error( + "Cannot execute operation because FlutterNapi is not attached to native."); + } + } + + private nativeNotifyLowMemoryWarning(nativeShellHolderId: number): void { + + } + + static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation { + return null; + } + + notifyLowMemoryWarning(): void { + this.ensureRunningOnMainThread(); + this.ensureAttachedToNative(); + this.nativeNotifyLowMemoryWarning(this.nativeShellHolderId); + } + + isAttached(): boolean { + return this.nativeShellHolderId != null; + } + + private ensureRunningOnMainThread(): void { + + } + + dispatchEmptyPlatformMessage(channel: String, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + flutter.nativeDispatchEmptyPlatformMessage(this.nativeShellHolderId, channel, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + /** Sends a reply {@code message} from Android to Flutter over the given {@code channel}. */ + dispatchPlatformMessage(channel: String, message: ArrayBuffer, position: number, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + + const uintArrayBuff = new Uint8Array(message) + let text = '' + for (let i = 0; i < uintArrayBuff.byteLength; i++) { + text += uintArrayBuff[i] + ',' + } + Log.w(TAG, "message=" + message.byteLength + ",text=" + text); + flutter.nativeDispatchPlatformMessage(this.nativeShellHolderId, channel, message, position, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + invokePlatformMessageEmptyResponseCallback(responseId: number): void { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageEmptyResponseCallback(this.nativeShellHolderId, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + invokePlatformMessageResponseCallback(responseId: number, message: ArrayBuffer, position: number) { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageResponseCallback( + this.nativeShellHolderId, responseId, message, position); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setViewportMetrics(devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array): void { + if (this.isAttached()) { + flutter.nativeSetViewportMetrics(this.nativeShellHolderId, devicePixelRatio, + physicalWidth, + physicalHeight, + physicalPaddingTop, + physicalPaddingRight, + physicalPaddingBottom, + physicalPaddingLeft, + physicalViewInsetTop, + physicalViewInsetRight, + physicalViewInsetBottom, + physicalViewInsetLeft, + systemGestureInsetTop, + systemGestureInsetRight, + systemGestureInsetBottom, + systemGestureInsetLeft, + physicalTouchSlop, + displayFeaturesBounds, + displayFeaturesType, + displayFeaturesState); + } + } + + spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array): FlutterNapi { + return new FlutterNapi(); + } + + addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(engineLifecycleListener); + } + + removeEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener) { + this.engineLifecycleListeners.delete(engineLifecycleListener); + } + + //Called by native to respond to a platform message that we sent. + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.w(TAG, "called handlePlatformMessageResponse Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handlePlatformMessageResponse(replyId, reply); + } + } + + // Called by native on any thread. + handlePlatformMessage(channel: string, message: ArrayBuffer, replyId: number, messageData: number): void { + Log.w(TAG, "called handlePlatformMessage Channel: " + channel + ". Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handleMessageFromDart(channel, message, replyId, messageData); + } + } + + // Called by native to notify first Flutter frame rendered. + onFirstFrame(): void { + Log.d(TAG, "called onFirstFrame") + } + + // Called by native. + onPreEngineRestart(): void { + Log.d(TAG, "called onPreEngineRestart") + this.engineLifecycleListeners.forEach( listener => listener.onPreEngineRestart()); + } + + // /** Invoked by native to obtain the results of OHOS's locale resolution algorithm. */ + computePlatformResolvedLocale(strings: Array): Array { + Log.d(TAG, "called computePlatformResolvedLocale " + JSON.stringify(strings)) + return [] + } + + decodeImage(buffer: ArrayBuffer, imageGeneratorAddress: number): void { + Log.d(TAG, "called decodeImage=" + buffer.byteLength) + const imageSourceApi = image.createImageSource(buffer); + let tempPixelMap: image.PixelMap = null; + imageSourceApi.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }).then(pixelMap => { + Log.d(TAG, "called createPixelMap end " + pixelMap.getPixelBytesNumber()) + tempPixelMap = pixelMap + return pixelMap.getImageInfo() + }).then(imageInfo => { + Log.d(TAG, `nativeImageHeaderCallback width=${imageInfo.size.width} height=${imageInfo.size.height} imageGeneratorAddress=${imageGeneratorAddress}`) + flutter.nativeImageDecodeCallback(imageInfo.size.width, imageInfo.size.height, imageGeneratorAddress, tempPixelMap) + }).catch((error: ESObject) => { + Log.d(TAG, "decodeImage error=" + JSON.stringify(error)) + flutter.nativeImageDecodeCallback(0, 0, imageGeneratorAddress, null); + }) + } + + setSemanticsEnabled(enabled: boolean, responseId: number): void { + if (this.isAttached()) { + this.nativeSetSemanticsEnabled(enabled); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + // Send an empty response to a platform message received from Dart. + nativeSetSemanticsEnabled(enabled: boolean):void {} + + setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { + if (this.isAttached()) { + this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeSetAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void {} + + dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { + if (this.isAttached()) { + this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeDispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void {} + + setAccessibilityDelegate(delegate: AccessibilityDelegate, responseId: number): void { + if (this.isAttached()) { + this.accessibilityDelegate = delegate; + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setLocalizationPlugin(localizationPlugin: LocalizationPlugin): void { + this.localizationPlugin = localizationPlugin; + } + + /** + * 获取系统语言列表 + * @param rate + */ + getSystemLanguages() { + Log.d(TAG, "called getSystemLanguages ") + let index: number; + let systemLanguages = i18n.System.getPreferredLanguageList(); + for (index = 0; index < systemLanguages.length; index++) { + Log.d(TAG, "systemlanguages "+ index + ":" + systemLanguages[index]); + } + flutter.nativeGetSystemLanguages(this.nativeShellHolderId, systemLanguages); + } +} + +export interface AccessibilityDelegate { + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void; + + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d63d83de313f52eba3f8fa6d2ed584f7bee44bd --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterOverlaySurface { + + private id: number; + + constructor(id: number) { + this.id = id + } + + getId(): number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a3cd75a49b7c53742072aa30541204060fc82e6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Want from '@ohos.app.ability.Want'; + +/** + * 封装flutter shell的参数 + */ +export default class FlutterShellArgs { + static ARG_KEY_TRACE_STARTUP = "trace-startup"; + static ARG_TRACE_STARTUP = "--trace-startup"; + static ARG_KEY_START_PAUSED = "start-paused"; + static ARG_START_PAUSED = "--start-paused"; + static ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; + static ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; + static ARG_KEY_ENDLESS_TRACE_BUFFER = "endless-trace-buffer"; + static ARG_ENDLESS_TRACE_BUFFER = "--endless-trace-buffer"; + static ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; + static ARG_USE_TEST_FONTS = "--use-test-fonts"; + static ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; + static ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; + static ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; + static ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; + static ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; + static ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; + static ARG_KEY_TRACE_SKIA = "trace-skia"; + static ARG_TRACE_SKIA = "--trace-skia"; + static ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; + static ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; + static ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; + static ARG_TRACE_SYSTRACE = "--trace-systrace"; + static ARG_KEY_ENABLE_IMPELLER = "enable-impeller"; + static ARG_ENABLE_IMPELLER = "--enable-impeller"; + static ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "dump-skp-on-shader-compilation"; + static ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "--dump-skp-on-shader-compilation"; + static ARG_KEY_CACHE_SKSL = "cache-sksl"; + static ARG_CACHE_SKSL = "--cache-sksl"; + static ARG_KEY_PURGE_PERSISTENT_CACHE = "purge-persistent-cache"; + static ARG_PURGE_PERSISTENT_CACHE = "--purge-persistent-cache"; + static ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; + static ARG_VERBOSE_LOGGING = "--verbose-logging"; + static ARG_KEY_OBSERVATORY_PORT = "observatory-port"; + static ARG_OBSERVATORY_PORT = "--observatory-port="; + static ARG_KEY_DART_FLAGS = "dart-flags"; + static ARG_DART_FLAGS = "--dart-flags"; + static ARG_KEY_MSAA_SAMPLES = "msaa-samples"; + static ARG_MSAA_SAMPLES = "--msaa-samples"; + + /** + * 从意图中解析参数,创建shellArgs + * @returns + */ + static fromWant(want: Want): FlutterShellArgs { + //tdo 解析want + return new FlutterShellArgs(); + } + + //参数 + args: Set = new Set(); + + add(arg: string) { + this.args.add(arg); + } + + remove(arg: string) { + this.args.delete(arg); + } + + toArray(): Array { + return Array.from(this.args); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d97b4835c0c87ed0c9d9260336b3a338392497f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets @@ -0,0 +1,379 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import resourceManager from '@ohos.resourceManager'; +import FlutterInjector from '../../../FlutterInjector'; +import { BinaryMessageHandler, BinaryReply, TaskQueue, TaskQueueOptions } from '../../../plugin/common/BinaryMessenger'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import StringCodec from '../../../plugin/common/StringCodec'; +import Log from '../../../util/Log'; +import { TraceSection } from '../../../util/TraceSection'; +import { FlutterCallbackInformation } from '../../../view/FlutterCallbackInformation'; +import FlutterNapi from '../FlutterNapi'; +import { DartMessenger } from './DartMessenger'; + + +const TAG = "DartExecutor"; + +/** + * dart代码执行器 + */ +export default class DartExecutor implements BinaryMessenger { + flutterNapi: FlutterNapi; + assetManager: resourceManager.ResourceManager; + private dartMessenger: DartMessenger; + private binaryMessenger: BinaryMessenger; + private isApplicationRunning: boolean; + private isolateServiceId: String = null; + private isolateServiceIdListener: IsolateServiceIdListener = null; + + private isolateChannelMessageHandler: BinaryMessageHandler = + new IsolateChannelMessageHandler(this.isolateServiceId, this.isolateServiceIdListener); + + constructor(flutterNapi: FlutterNapi, assetManager: resourceManager.ResourceManager) { + this.flutterNapi = flutterNapi; + this.assetManager = assetManager; + this.dartMessenger = new DartMessenger(flutterNapi); + this.dartMessenger.setMessageHandler("flutter/isolate", this.isolateChannelMessageHandler); + this.binaryMessenger = new DefaultBinaryMessenger(this.dartMessenger); + // The JNI might already be attached if coming from a spawned engine. If so, correctly report + // that this DartExecutor is already running. + if (flutterNapi.isAttached()) { + this.isApplicationRunning = true; + } + } + + + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * DartExecutor} attaches to JNI. + * + *

When attached to JNI, this {@link DartExecutor} begins handling 2-way communication to/from + * the Dart execution context. This communication is facilitate via 2 APIs: + * + *

    + *
  • {@link BinaryMessenger}, which sends messages to Dart + *
  • {@link PlatformMessageHandler}, which receives messages from Dart + *
+ */ + onAttachedToNAPI(): void { + Log.d(TAG, "Attached to NAPI. Registering the platform message handler for this Dart execution context."); + this.flutterNapi.setPlatformMessageHandler(this.dartMessenger); + } + + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * DartExecutor} detaches from JNI. + * + *

When detached from JNI, this {@link DartExecutor} stops handling 2-way communication to/from + * the Dart execution context. + */ + onDetachedFromNAPI(): void { + Log.d(TAG, "Detached from NAPI. De-registering the platform message handler for this Dart execution context."); + this.flutterNapi.setPlatformMessageHandler(null); + } + + /** + * Is this {@link DartExecutor} currently executing Dart code? + * + * @return true if Dart code is being executed, false otherwise + */ + isExecutingDart(): boolean { + return this.isApplicationRunning; + } + + /** + * Starts executing Dart code based on the given {@code dartEntrypoint} and the {@code + * dartEntrypointArgs}. + * + *

See {@link DartEntrypoint} for configuration options. + * + * @param dartEntrypoint specifies which Dart function to run, and where to find it + * @param dartEntrypointArgs Arguments passed as a list of string to Dart's entrypoint function. + */ + executeDartEntrypoint(dartEntrypoint: DartEntrypoint, dartEntrypointArgs?: string[]): void { + if (this.isApplicationRunning) { + Log.w(TAG, "Attempted to run a DartExecutor that is already running."); + return; + } + + TraceSection.begin("DartExecutor#executeDartEntrypoint"); + try { + Log.d(TAG, "Executing Dart entrypoint: " + dartEntrypoint); + this.flutterNapi.runBundleAndSnapshotFromLibrary( + dartEntrypoint.pathToBundle, + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + this.assetManager, + dartEntrypointArgs); + + this.isApplicationRunning = true; + } finally { + TraceSection.end("DartExecutor#executeDartEntrypoint"); + } + } + + /** + * Starts executing Dart code based on the given {@code dartCallback}. + * + *

See {@link DartCallback} for configuration options. + * + * @param dartCallback specifies which Dart callback to run, and where to find it + */ + executeDartCallback(dartCallback: DartCallback): void { + if (this.isApplicationRunning) { + Log.w(TAG, "Attempted to run a DartExecutor that is already running."); + return; + } + + TraceSection.begin("DartExecutor#executeDartCallback"); + try { + Log.d(TAG, "Executing Dart callback: " + dartCallback); + this.flutterNapi.runBundleAndSnapshotFromLibrary( + dartCallback.pathToBundle, + dartCallback.callbackHandle.callbackName, + dartCallback.callbackHandle.callbackLibraryPath, + dartCallback.resourceManager, + null); + + this.isApplicationRunning = true; + } finally { + TraceSection.end("DartExecutor#executeDartCallback"); + } + } + + /** + * Returns a {@link BinaryMessenger} that can be used to send messages to, and receive messages + * from, Dart code that this {@code DartExecutor} is executing. + */ + + getBinaryMessenger(): BinaryMessenger { + return this.binaryMessenger; + } + + makeBackgroundTaskQueue(options: TaskQueueOptions): TaskQueue { + return this.getBinaryMessenger().makeBackgroundTaskQueue(options); + } + + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + this.getBinaryMessenger().send(channel, message, callback); + } + + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void { + this.getBinaryMessenger().setMessageHandler(channel, handler, taskQueue); + } + + enableBufferingIncomingMessages(): void { + this.getBinaryMessenger().enableBufferingIncomingMessages(); + } + + + /** + * Returns the number of pending channel callback replies. + * + *

When sending messages to the Flutter application using {@link BinaryMessenger#send(String, + * ByteBuffer, io.flutter.plugin.common.BinaryMessenger.BinaryReply)}, developers can optionally + * specify a reply callback if they expect a reply from the Flutter application. + * + *

This method tracks all the pending callbacks that are waiting for response, and is supposed + * to be called from the main thread (as other methods). Calling from a different thread could + * possibly capture an indeterministic internal state, so don't do it. + * + *

Currently, it's mainly useful for a testing framework like Espresso to determine whether all + * the async channel callbacks are handled and the app is idle. + */ + getPendingChannelResponseCount(): number { + return this.dartMessenger.getPendingChannelResponseCount(); + } + + /** + * Returns an identifier for this executor's primary isolate. This identifier can be used in + * queries to the Dart service protocol. + */ + + getIsolateServiceId(): String { + return this.isolateServiceId; + } + + + + /** + * Set a listener that will be notified when an isolate identifier is available for this + * executor's primary isolate. + */ + setIsolateServiceIdListener(listener: IsolateServiceIdListener): void { + this.isolateServiceIdListener = listener; + if (this.isolateServiceIdListener != null && this.isolateServiceId != null) { + this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); + } + } + + /** + * Notify the Dart VM of a low memory event, or that the application is in a state such that now + * is an appropriate time to free resources, such as going to the background. + * + *

This does not notify a Flutter application about memory pressure. For that, use the {@link + * io.flutter.embedding.engine.systemchannels.SystemChannel#sendMemoryPressureWarning}. + * + *

Calling this method may cause jank or latency in the application. Avoid calling it during + * critical periods like application startup or periods of animation. + */ + notifyLowMemoryWarning(): void { + if (this.flutterNapi.isAttached()) { + this.flutterNapi.notifyLowMemoryWarning(); + } + } + + disableBufferingIncomingMessages(): void { + this.getBinaryMessenger().enableBufferingIncomingMessages(); + } +} + + +/** + * Configuration options that specify which Dart entrypoint function is executed and where to find + * that entrypoint and other assets required for Dart execution. + */ +export class DartEntrypoint { + /** The path within the AssetManager where the app will look for assets. */ + pathToBundle: string; + + /** The library or file location that contains the Dart entrypoint function. */ + dartEntrypointLibrary: string; + + /** The name of a Dart function to execute. */ + dartEntrypointFunctionName: string; + + constructor(pathToBundle: string, + dartEntrypointLibrary: string, + dartEntrypointFunctionName: string) { + this.pathToBundle = pathToBundle; + this.dartEntrypointLibrary = dartEntrypointLibrary; + this.dartEntrypointFunctionName = dartEntrypointFunctionName; + } + + static createDefault() { + const flutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!flutterLoader.initialized) { + throw new Error( + "DartEntrypoints can only be created once a FlutterEngine is created."); + } + return new DartEntrypoint(flutterLoader.findAppBundlePath(), null, "main"); + } +} + + +/** Callback interface invoked when the isolate identifier becomes available. */ +interface IsolateServiceIdListener { + onIsolateServiceIdAvailable(isolateServiceId: String): void; +} + + +/** + * Configuration options that specify which Dart callback function is executed and where to find + * that callback and other assets required for Dart execution. + */ +export class DartCallback { + /** Standard Android AssetManager, provided from some {@code Context} or {@code Resources}. */ + public resourceManager: resourceManager.ResourceManager; + + /** The path within the AssetManager where the app will look for assets. */ + public pathToBundle: string; + + /** A Dart callback that was previously registered with the Dart VM. */ + public callbackHandle: FlutterCallbackInformation; + + constructor(resourceManager: resourceManager.ResourceManager, + pathToBundle: string, + callbackHandle: FlutterCallbackInformation) { + this.resourceManager = resourceManager; + this.pathToBundle = pathToBundle; + this.callbackHandle = callbackHandle; + } + + toString(): String { + return "DartCallback( bundle path: " + + this.pathToBundle + + ", library path: " + + this.callbackHandle.callbackLibraryPath + + ", function: " + + this.callbackHandle.callbackName + + " )"; + } +} + +export class DefaultBinaryMessenger implements BinaryMessenger { + private messenger: DartMessenger; + + constructor(messenger: DartMessenger) { + this.messenger = messenger; + } + + makeBackgroundTaskQueue(options: TaskQueueOptions): TaskQueue { + return this.messenger.makeBackgroundTaskQueue(options); + } + + /** + * Sends the given {@code messages} from Android to Dart over the given {@code channel} and then + * has the provided {@code callback} invoked when the Dart side responds. + * + * @param channel the name of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a callback invoked when the Dart application responds to the message + */ + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + this.messenger.send(channel, message, callback); + } + + /** + * Sets the given {@link io.flutter.plugin.common.BinaryMessenger.BinaryMessageHandler} as the + * singular handler for all incoming messages received from the Dart side of this Dart execution + * context. + * + * @param channel the name of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + */ + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void { + this.messenger.setMessageHandler(channel, handler); + } + + enableBufferingIncomingMessages(): void { + this.messenger.enableBufferingIncomingMessages(); + } + + disableBufferingIncomingMessages(): void { + this.messenger.disableBufferingIncomingMessages(); + } +} + +class IsolateChannelMessageHandler implements BinaryMessageHandler { + private isolateServiceId: String; + private isolateServiceIdListener: IsolateServiceIdListener; + + constructor(isolateServiceId: String, isolateServiceIdListener: IsolateServiceIdListener) { + this.isolateServiceId = isolateServiceId; + this.isolateServiceIdListener = isolateServiceIdListener; + } + + onMessage(message: ArrayBuffer, callback: BinaryReply): void { + this.isolateServiceId = StringCodec.INSTANCE.decodeMessage(message); + if (this.isolateServiceIdListener != null) { + this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b8695530d69f9e49063913d559702863490676a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log' +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue, TaskQueueOptions } from '../../../plugin/common/BinaryMessenger'; +import FlutterNapi from '../FlutterNapi'; +import { PlatformMessageHandler } from './PlatformMessageHandler'; +import { TraceSection } from '../../../util/TraceSection'; + +/** + * Message conduit for 2-way communication between Android and Dart. + * + *

See {@link BinaryMessenger}, which sends messages from Android to Dart + * + *

See {@link PlatformMessageHandler}, which handles messages to Android from Dart + */ + +const TAG = "DartMessenger"; + +export class DartMessenger implements BinaryMessenger, PlatformMessageHandler { + + flutterNapi: FlutterNapi; + + /** + * Maps a channel name to an object that contains the task queue and the handler associated with + * the channel. + * + *

Reads and writes to this map must lock {@code handlersLock}. + */ + messageHandlers: Map = new Map(); + + /** + * Maps a channel name to an object that holds information about the incoming Dart message. + * + *

Reads and writes to this map must lock {@code handlersLock}. + */ + bufferedMessages: Map = new Map(); + + handlersLock: Object = new Object(); + enableBufferingIncomingMessagesFlag: boolean = false; + + pendingReplies: Map = new Map(); + nextReplyId: number = 1; + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi; + } + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue { + throw new Error('Method not implemented.'); + } + + + setMessageHandler(channel: String, handler: BinaryMessageHandler): void { + if (handler == null) { + Log.d(TAG, "Removing handler for channel '" + channel + "'"); + this.messageHandlers.delete(channel); + return; + } + Log.d(TAG, "Setting handler for channel '" + channel + "'"); + + this.messageHandlers.set(channel, new HandlerInfo(handler)); + this.bufferedMessages.delete(channel); + } + + + enableBufferingIncomingMessages(): void { + this.enableBufferingIncomingMessagesFlag = true; + } + + disableBufferingIncomingMessages(): void { + this.enableBufferingIncomingMessagesFlag = false; + this.bufferedMessages = new Map(); + } + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + Log.d(TAG, "Sending message over channel '" + channel + "'"); + TraceSection.begin("DartMessenger#send on " + channel); + try { + Log.d(TAG, "Sending message with callback over channel '" + channel + "'"); + let replyId: number = this.nextReplyId++; + if (callback != null) { + this.pendingReplies.set(replyId, callback); + } + if (message == null) { + this.flutterNapi.dispatchEmptyPlatformMessage(channel, replyId); + } else { + this.flutterNapi.dispatchPlatformMessage(channel, message, message.byteLength, replyId); + } + } finally { + TraceSection.end("DartMessenger#send on " + channel); + } + } + + invokeHandler(handlerInfo: HandlerInfo, message: ArrayBuffer, replyId: number): void { + // Called from any thread. + if (handlerInfo != null) { + try { + Log.d(TAG, "Deferring to registered handler to process message."); + handlerInfo.handler.onMessage(message, new Reply(this.flutterNapi, replyId)); + } catch (ex) { + Log.e(TAG, "Uncaught exception in binary message listener", ex); + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); + } + } else { + Log.d(TAG, "No registered handler for message. Responding to Dart with empty reply message."); + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); + } + } + + handleMessageFromDart(channel: String, message: ArrayBuffer, replyId: number, messageData: number): void { + // Called from any thread. + Log.d(TAG, "Received message from Dart over channel '" + channel + "'"); + + let handlerInfo: HandlerInfo; + let messageDeferred: boolean; + handlerInfo = this.messageHandlers.get(channel); + messageDeferred = (this.enableBufferingIncomingMessagesFlag && handlerInfo == null); + if (messageDeferred) { + if (!this.bufferedMessages.has(channel)) { + // this.bufferedMessages.set(channel, new BufferedMessageInfo[0]); + this.bufferedMessages.set(channel, null); + } + let buffer: BufferedMessageInfo[] = this.bufferedMessages.get(channel); + buffer.push(new BufferedMessageInfo(message, replyId, messageData)); + } + if (!messageDeferred) { + this.invokeHandler(handlerInfo, message, replyId); + } + } + + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.d(TAG, "Received message reply from Dart."); + let callback: BinaryReply = this.pendingReplies.get(replyId); + this.pendingReplies.delete(replyId); + if (callback != null) { + try { + Log.d(TAG, "Invoking registered callback for reply from Dart."); + callback.reply(reply); + } catch (e) { + Log.e(TAG, "Uncaught exception in binary message reply handler", e); + } + } + } + + /** + * Returns the number of pending channel callback replies. + * + *

When sending messages to the Flutter application using {@link BinaryMessenger#send(String, + * ByteBuffer, io.flutter.plugin.common.BinaryMessenger.BinaryReply)}, developers can optionally + * specify a reply callback if they expect a reply from the Flutter application. + * + *

This method tracks all the pending callbacks that are waiting for response, and is supposed + * to be called from the main thread (as other methods). Calling from a different thread could + * possibly capture an indeterministic internal state, so don't do it. + */ + getPendingChannelResponseCount(): number { + return this.pendingReplies.size; + } +} + + + + + + +/** + * Holds information about a platform handler, such as the task queue that processes messages from + * Dart. + */ +class HandlerInfo { + handler: BinaryMessageHandler; + + constructor(handler: BinaryMessageHandler) { + this.handler = handler; + } +} + +/** + * Holds information that allows to dispatch a Dart message to a platform handler when it becomes + * available. + */ +class BufferedMessageInfo { + message: ArrayBuffer; + replyId: number; + messageData: number; + + constructor(message: ArrayBuffer, + replyId: number, + messageData: number) { + this.message = message; + this.replyId = replyId; + this.messageData = messageData; + } +} + + + + + +class Reply implements BinaryReply { + flutterNapi: FlutterNapi; + replyId: number; + done: boolean = false; + + constructor(flutterNapi: FlutterNapi, replyId: number) { + this.flutterNapi = flutterNapi; + this.replyId = replyId; + } + + reply(reply: ArrayBuffer) { + if (this.done) { + throw new Error("Reply already submitted"); + } + if (reply == null) { + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(this.replyId); + } else { + this.flutterNapi.invokePlatformMessageResponseCallback(this.replyId, reply, reply.byteLength); + } + } +} + +interface DartMessengerTaskQueue { + dispatch(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets new file mode 100644 index 0000000000000000000000000000000000000000..b6e3411862cb936f4e9af2c6e0ab6a49be3c9dce --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export interface PlatformMessageHandler { + + handleMessageFromDart(channel: String,message: ArrayBuffer,replyId: number, messageData: number): void; + + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void; + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets new file mode 100644 index 0000000000000000000000000000000000000000..b8af4f6fb756f4e344e5040d828244ada46d0783 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterApplicationInfo from './FlutterApplicationInfo'; +import common from '@ohos.app.ability.common'; + +export default class ApplicationInfoLoader { + static load(context: common.Context) { + let applicatioinInfo = new FlutterApplicationInfo(null, null, null, null, null, context.bundleCodeDir + '/libs/arm64', true); + return applicatioinInfo + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..0db68ee9da2876e12e9c50734c68c2781469b0c4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +const DEFAULT_AOT_SHARED_LIBRARY_NAME = "libapp.so"; +const DEFAULT_VM_SNAPSHOT_DATA = "vm_snapshot_data"; +const DEFAULT_ISOLATE_SNAPSHOT_DATA = "isolate_snapshot_data"; +const DEFAULT_FLUTTER_ASSETS_DIR = "flutter_assets"; + + +/** + * application 信息,后期看如何设置 + */ +export default class FlutterApplicationInfo { + aotSharedLibraryName: string; + vmSnapshotData: string; + isolateSnapshotData: string; + flutterAssetsDir: string; + domainNetworkPolicy: string; + nativeLibraryDir: string; + automaticallyRegisterPlugins: boolean; + //是否是开发模式,先放在这里,后续应该从context获取 + isDebugMode: boolean; + //是否是profile模式 + isProfile: boolean; + + constructor(aotSharedLibraryName: string, vmSnapshotData: string, isolateSnapshotData: string, flutterAssetsDir: string, domainNetworkPolicy: string, + nativeLibraryDir: string, automaticallyRegisterPlugins: boolean) { + this.aotSharedLibraryName = aotSharedLibraryName == null ? DEFAULT_AOT_SHARED_LIBRARY_NAME : aotSharedLibraryName; + this.vmSnapshotData = vmSnapshotData == null ? DEFAULT_VM_SNAPSHOT_DATA : vmSnapshotData; + this.isolateSnapshotData = isolateSnapshotData == null ? DEFAULT_ISOLATE_SNAPSHOT_DATA : isolateSnapshotData; + this.flutterAssetsDir = flutterAssetsDir == null ? DEFAULT_FLUTTER_ASSETS_DIR : flutterAssetsDir; + this.domainNetworkPolicy = domainNetworkPolicy == null ? "" : domainNetworkPolicy; + this.nativeLibraryDir = nativeLibraryDir; + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + this.isDebugMode = true; + this.isProfile = false; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets new file mode 100644 index 0000000000000000000000000000000000000000..114387d16e7a585188aedb535fa62b8671d7a7b7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * flutterLoader,负责dart虚拟机启动和dart代码加载 + */ +import FlutterShellArgs from '../FlutterShellArgs'; +import FlutterNapi from '../FlutterNapi'; +import Log from '../../../util/Log'; +import FlutterApplicationInfo from './FlutterApplicationInfo'; +import common from '@ohos.app.ability.common'; +import StringUtils from '../../../util/StringUtils'; +import ApplicationInfoLoader from './ApplicationInfoLoader'; +import bundleManager from '@ohos.bundle.bundleManager'; +import fs from '@ohos.file.fs'; + +const TAG = "FlutterLoader"; + +//flutter引擎so +const DEFAULT_LIBRARY = "libflutter.so"; +//jit产物默认kenel文件 +const DEFAULT_KERNEL_BLOB = "kernel_blob.bin"; +//jit产物,默认快照文件 +const VMSERVICE_SNAPSHOT_LIBRARY = "libvmservice_snapshot.so"; +//key值 +const SNAPSHOT_ASSET_PATH_KEY = "snapshot-asset-path"; +//key值 +const VM_SNAPSHOT_DATA_KEY = "vm-snapshot-data"; +//key值 +const ISOLATE_SNAPSHOT_DATA_KEY = "isolate-snapshot-data"; + + +const AOT_SHARED_LIBRARY_NAME = "aot-shared-library-name"; + +const AOT_VMSERVICE_SHARED_LIBRARY_NAME = "aot-vmservice-shared-library-name"; + +//文件路径分隔符 +const FILE_SEPARATOR = "/"; + +/** + * 定位在hap包中的flutter资源,并且加载flutter native library. + */ +export default class FlutterLoader { + flutterNapi: FlutterNapi; + initResult: InitResult; + flutterApplicationInfo: FlutterApplicationInfo; + context: common.Context; + initialized: boolean; + //初始化开始时间戳 + initStartTimestampMillis: number; + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi; + } + + /** + * Starts initialization of the native system. + * + *

This loads the Flutter engine's native library to enable subsequent JNI calls. This also + * starts locating and unpacking Dart resources packaged in the app's APK. + * + *

Calling this method multiple times has no effect. + * + * @param applicationContext The Android application context. + * @param settings Configuration settings. + */ + async startInitialization(context: common.Context) { + Log.d(TAG, "flutterLoader start init") + this.initStartTimestampMillis = Date.now(); + this.context = context; + this.flutterApplicationInfo = ApplicationInfoLoader.load(context); + Log.d(TAG, "context.filesDir=" + context.filesDir) + Log.d(TAG, "context.cacheDir=" + context.cacheDir) + Log.d(TAG, "context.bundleCodeDir=" + context.bundleCodeDir) + if (this.flutterApplicationInfo.isDebugMode) { + await this.copyResource(context) + } + this.initResult = new InitResult( + `${context.filesDir}/`, + `${context.cacheDir}/`, + `${context.filesDir}` + ) + Log.d(TAG, "flutterLoader end init") + } + + private async copyResource(context: common.Context) { + let filePath = context.filesDir + FILE_SEPARATOR + this.flutterApplicationInfo.flutterAssetsDir + if (!fs.accessSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB)) { + Log.d(TAG, "start copyResource") + fs.mkdirSync(filePath) + + let icudtlBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + "/icudtl.dat") + let icudtlFile = fs.openSync(filePath + FILE_SEPARATOR + "/icudtl.dat", fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(icudtlFile.fd, icudtlBuffer.buffer) + + let kernelBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB) + let kernelFile = fs.openSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(kernelFile.fd, kernelBuffer.buffer) + + let vmBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + this.flutterApplicationInfo.vmSnapshotData) + let vmFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo.vmSnapshotData, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(vmFile.fd, vmBuffer.buffer) + + let isolateBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + this.flutterApplicationInfo.isolateSnapshotData) + let isolateFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo.isolateSnapshotData, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(isolateFile.fd, isolateBuffer.buffer) + Log.d(TAG, "copyResource end") + } else { + Log.d(TAG, "no copyResource") + } + } + + /** + * 初始化dart虚拟机方法 + * @param flutterShellArgs + */ + ensureInitializationComplete(shellArgs: Array) { + if (this.initialized) { + return; + } + Log.d(TAG, "ensureInitializationComplete") + if (shellArgs == null) { + shellArgs = new Array(); + } + shellArgs.push( + "--icu-native-lib-path=" + + this.flutterApplicationInfo.nativeLibraryDir + + FILE_SEPARATOR + DEFAULT_LIBRARY + ); + + let kernelPath: string = ""; + if (this.flutterApplicationInfo.isDebugMode) { + Log.d(TAG, "this.initResult.dataDirPath=" + this.initResult.dataDirPath) + const snapshotAssetPath = this.initResult.dataDirPath + FILE_SEPARATOR + this.flutterApplicationInfo.flutterAssetsDir; + kernelPath = snapshotAssetPath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB; + shellArgs.push("--icu-data-file-path=" + snapshotAssetPath + "/icudtl.dat") + shellArgs.push("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath); + shellArgs.push("--" + VM_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo.vmSnapshotData); + shellArgs.push( + "--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo.isolateSnapshotData); + } else { + shellArgs.push( + "--" + AOT_SHARED_LIBRARY_NAME + "=" + this.flutterApplicationInfo.aotSharedLibraryName); + shellArgs.push( + "--" + + AOT_SHARED_LIBRARY_NAME + + "=" + + this.flutterApplicationInfo.nativeLibraryDir + + FILE_SEPARATOR + + this.flutterApplicationInfo.aotSharedLibraryName); + if (this.flutterApplicationInfo.isProfile) { + shellArgs.push("--" + AOT_VMSERVICE_SHARED_LIBRARY_NAME + "=" + VMSERVICE_SNAPSHOT_LIBRARY); + } + } + shellArgs.push("--cache-dir-path=" + this.initResult.engineCachesPath); + if (StringUtils.isNotEmpty(this.flutterApplicationInfo.domainNetworkPolicy)) { + shellArgs.push("--domain-network-policy=" + this.flutterApplicationInfo.domainNetworkPolicy); + } + + const resourceCacheMaxBytesThreshold = 1080 * 1920 * 12 * 4; + shellArgs.push("--resource-cache-max-bytes-threshold=" + resourceCacheMaxBytesThreshold); + + shellArgs.push("--prefetched-default-font-manager"); + + shellArgs.push("--leak-vm=" + true); + + //shellArgs.push("--enable-impeller"); + + // //最终初始化操作 + const costTime = Date.now() - this.initStartTimestampMillis; + this.flutterNapi.init( + this.context, + shellArgs, + kernelPath, + this.initResult.appStoragePath, + this.initResult.engineCachesPath, + costTime + ); + this.initialized = true; + } + + findAppBundlePath(): string { + return this.flutterApplicationInfo.flutterAssetsDir; + } + + getLookupKeyForAsset(asset: string, packageName?: string): string { + return this.fullAssetPathFrom(asset); + } + + fullAssetPathFrom(filePath: string): string { + return this.flutterApplicationInfo.flutterAssetsDir + "/" + filePath; + } +} + +class InitResult { + appStoragePath: string; + engineCachesPath: string; + dataDirPath: string; + + constructor(appStoragePath: string, + engineCachesPath: string, + dataDirPath: string) { + this.appStoragePath = appStoragePath; + this.engineCachesPath = engineCachesPath; + this.dataDirPath = dataDirPath; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets new file mode 100644 index 0000000000000000000000000000000000000000..9ed8ce3bf7294ef365e3ba61c5133fb61f54d058 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + import ArrayList from '@ohos.util.ArrayList'; +import matrix4 from '@ohos.matrix4'; +import { DVModel, DVModelEvents, DVModelParameters } from '../../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../../view/DynamicView/dynamicViewJson'; +import OhosTouchProcessor from '../../ohos/OhosTouchProcessor'; +import { FlutterMutator, FlutterMutatorsStack } from './FlutterMutatorsStack' + +export class FlutterMutatorView { + private mutatorsStack: FlutterMutatorsStack; + private screenDensity: number; + private left: number; + private top: number; + private prevLeft: number; + private prevTop: number; + private ohosTouchProcessor: OhosTouchProcessor; + private onTouch = (touchEvent: ESObject) => { + let params = this.model.params as Record; + switch (touchEvent.type) { + case TouchType.Down: + this.prevLeft = this.left; + this.prevTop = this.top; + // this.model.params["translateX"] = this.left; + // this.model.params["translateY"] = this.top; + params.translateX = this.left; + params.translateY = this.top; + break; + case TouchType.Move: + // this.model.params["translateX"] = this.prevLeft; + // this.model.params["translateY"] = this.prevTop; + params.translateX = this.prevLeft; + params.translateY = this.prevTop; + this.prevLeft = this.left; + this.prevTop = this.top; + break; + case TouchType.Up: + case TouchType.Cancel: + default: + break; + } + } + + private model: DVModel = createDVModelFromJson( + new DVModelParam("Column", [], { backgroundColor: Color.Red }, { onTouch: this.onTouch }) + ); + + setOnDescendantFocusChangeListener(onFocus: () => void, onBlur: () => void) { + // this.model.events["onFocus"] = onFocus; + // this.model.events["onBlur"] = onBlur; + let events2 = this.model.events as Record; + events2.onFocus = onFocus; + events2.onBlur = onBlur; + } + + public setLayoutParams(parameters: DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + let params = this.model.params as Record | matrix4.Matrix4Transit>; + let parametersRecord = parameters as Record | matrix4.Matrix4Transit>; + // this.model.params['marginLeft'] = parameters['marginLeft']; + // this.model.params['marginTop'] = parameters['marginTop']; + // this.model.params['width'] = parameters['width']; + // this.model.params['height'] = parameters['height']; + params.marginLeft = parametersRecord['marginLeft']; + params.marginTop = parametersRecord['marginTop']; + params.width = parametersRecord['width']; + params.height = parametersRecord['height']; + // this.left = parameters['marginLeft']; + // this.top = parameters['marginTop']; + this.left = parametersRecord.marginLeft as number; + this.top = parametersRecord.marginTop as number ; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } + + public readyToDisplay(mutatorsStack: FlutterMutatorsStack, left: number, top: number, width: number, height: number) { + this.mutatorsStack = mutatorsStack; + this.left = left; + this.top = top; + let parameters = new DVModelParameters() as Record | matrix4.Matrix4Transit>; + parameters['marginLeft'] = left; + parameters['marginTop'] = top; + parameters['width'] = width; + parameters['height'] = height; + this.setLayoutParams(parameters); + this.dealMutators(); + } + + private dealMutators() { + let paths = this.mutatorsStack.getFinalClippingPaths(); + let rects = this.mutatorsStack.getFinalClippingRects(); + let matrix = this.mutatorsStack.getFinalMatrix(); + let params = this.model.params as Record | matrix4.Matrix4Transit>; + if (!paths.isEmpty()) { + let path = paths.getLast(); + // this.model.params["pathWidth"] = path.width; + // this.model.params["pathHeight"] = path.height; + // this.model.params["pathCommands"] = path.commands; + params.pathWidth = path.width; + params.pathHeight = path.height; + params.pathCommands = path.commands; + } + if (!rects.isEmpty()) { + let rect = rects.getLast(); + // this.model.params["rectWidth"] = rect.width; + // this.model.params["rectHeight"] = rect.height; + // this.model.params["rectRadius"] = rect.radius; + params.rectWidth = rect.width; + params.rectHeight = rect.height; + params.rectRadius = rect.radius; + } + // this.model.params["matrix"] = matrix; + params.matrix = matrix; + } + + public getDvModel(): DVModel { + return this.model; + } +} + +class DVModelParam { + compType: string + children: [] + attributes: ESObject + events: ESObject + + constructor(compType: string, children: [], attributes: ESObject, events: ESObject) { + this.compType = compType; + this.children = children; + this.attributes = attributes; + this.events = events; + } +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets new file mode 100644 index 0000000000000000000000000000000000000000..8261becf2f1d716f162e2c45093dce8e30cc5d05 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + import matrix4 from '@ohos.matrix4' +import List from '@ohos.util.List'; + +export enum FlutterMutatorType { + CLIP_RECT, + CLIP_PATH, + TRANSFORM, + OPACITY +} + +class Rect { + width: number; + height: number; + radius?: string | number | Array; + + constructor(width:number, height:number, radius?:string | number | Array) { + this.width = width; + this.height = height; + this.radius = radius; + } +} + +class Path { + width: number | string; + height: number | string; + commands?: string; + + constructor(width:number | string, height:number | string, commands?:string) { + this.width = width; + this.height = height; + this.commands = commands; + } +} + +export class FlutterMutator { + private matrix: matrix4.Matrix4Transit; + private rect: Rect; + private path: Path; + + constructor(args: matrix4.Matrix4Transit | Rect | Path) { + if (args instanceof Rect) { + this.rect = args; + } else if (args instanceof Path) { + this.path = args; + } else { + this.matrix = args; + } + } + + public getMatrix() { + return this.matrix; + } + + public getRect() { + return this.rect; + } + + public getPath() { + return this.path; + } +} + +export class FlutterMutatorsStack { + private mutators: List; + private finalClippingPaths: List; + private finalClippingRects: List; + + private finalMatrix: matrix4.Matrix4Transit; + + constructor() { + this.mutators = new List(); + this.finalClippingPaths = new List(); + this.finalClippingRects = new List(); + this.finalMatrix = matrix4.identity(); + } + + public pushTransform(values: Array): void { + if (values.length != 16) { + return; + } + let index = 0; + let matrix = matrix4.init( + [values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++]]); + let mutator = new FlutterMutator(matrix); + this.mutators.add(mutator); + this.finalMatrix.combine(matrix); + } + + public pushClipRect(width:number, height:number, radius?:number) { + let rect = new Rect(width, height, radius); + let mutator = new FlutterMutator(rect); + this.mutators.add(mutator); + this.finalClippingRects.add(rect); + } + + public pushClipPath(width:number, height:number, command?:string) { + let path = new Path(width, height, command); + let mutator = new FlutterMutator(path); + this.mutators.add(mutator); + this.finalClippingPaths.add(path); + } + + public getMutators() { + return this.mutators; + } + + public getFinalClippingPaths() { + return this.finalClippingPaths; + } + + public getFinalClippingRects() { + return this.finalClippingRects; + } + + public getFinalMatrix() { + return this.finalMatrix; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..3045e2b8d7ddf48a11d96a642650c63a3f6c0025 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import PlatformViewRegistry from '../../../plugin/platform/PlatformViewRegistry'; +import FlutterEngineGroup from '../FlutterEngineGroup'; + +export interface FlutterPlugin { + //获取唯一的类名 类似安卓的ClassRelevant resources that this {@code FlutterPlugin} may need are provided via the {@code + * binding}. The {@code binding} may be cached and referenced until {@link + * #onDetachedFromEngine(FlutterPluginBinding)} is invoked and returns. + */ + onAttachedToEngine(binding: FlutterPluginBinding): void; + + /** + * This {@code FlutterPlugin} has been removed from a {@link + * io.flutter.embedding.engine.FlutterEngine} instance. + * + *

The {@code binding} passed to this method is the same instance that was passed in {@link + * #onAttachedToEngine(FlutterPluginBinding)}. It is provided again in this method as a + * convenience. The {@code binding} may be referenced during the execution of this method, but it + * must not be cached or referenced after this method returns. + * + *

{@code FlutterPlugin}s should release all resources in this method. + */ + onDetachedFromEngine(binding: FlutterPluginBinding): void; +} + +export class FlutterPluginBinding { + private applicationContext: common.Context; + private binaryMessenger: BinaryMessenger; + private flutterAssets: FlutterAssets; + private group: FlutterEngineGroup; + private platformViewRegistry: PlatformViewRegistry; + + constructor(applicationContext: common.Context, binaryMessenger: BinaryMessenger, flutterAssets: FlutterAssets, group: FlutterEngineGroup, platformViewRegistry?: PlatformViewRegistry) { + this.applicationContext = applicationContext; + this.binaryMessenger = binaryMessenger; + this.flutterAssets = flutterAssets; + this.group = group; + this.platformViewRegistry = platformViewRegistry; + } + + getApplicationContext(): common.Context { + return this.applicationContext; + } + + getBinaryMessenger(): BinaryMessenger { + return this.binaryMessenger; + } + + getFlutterAssets(): FlutterAssets { + return this.flutterAssets; + } + + getEngineGroup(): FlutterEngineGroup { + return this.group; + } + + public getPlatformViewRegistry(): PlatformViewRegistry { + return this.platformViewRegistry; + } +} + +/** Provides Flutter plugins with access to Flutter asset information. */ +export interface FlutterAssets { + /** + * Returns the relative file path to the Flutter asset with the given name, including the file's + * extension, e.g., {@code "myImage.jpg"}. + * + *

The returned file path is relative to the Ohos app's standard assets directory. + * Therefore, the returned path is appropriate to pass to Ohos's {@code ResourceManage}, but + * the path is not appropriate to load as an absolute path. + */ + getAssetFilePathByName(assetFileName: string): string; + + /** + * Same as {@link #getAssetFilePathByName(String)} but with added support for an explicit + * Ohos {@code bundleName}. + */ + getAssetFilePathByName(assetFileName: string, bundleName: string): string; + + /** + * Returns the relative file path to the Flutter asset with the given subpath, including the + * file's extension, e.g., {@code "/dir1/dir2/myImage.jpg"}. + * + *

The returned file path is relative to the Ohos app's standard assets directory. + * Therefore, the returned path is appropriate to pass to Ohos's {@code ResourceManage}, but + * the path is not appropriate to load as an absolute path. + */ + getAssetFilePathBySubpath(assetSubpath: string): string; + + /** + * Same as {@link #getAssetFilePathBySubpath(String)} but with added support for an explicit + * Ohos {@code bundleName}. + */ + getAssetFilePathBySubpath(assetSubpath: string, bundleName: string): string; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a322ec2ba1bbcfcbce180b00ec4df6356733180 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterPlugin } from './FlutterPlugin'; + +export default interface PluginRegistry { + /** + * Attaches the given {@code plugin} to the {@link io.flutter.embedding.engine.FlutterEngine} + * associated with this {@code PluginRegistry}. + */ + add(plugin: FlutterPlugin): void; + + /** + * Attaches the given {@code plugins} to the {@link io.flutter.embedding.engine.FlutterEngine} + * associated with this {@code PluginRegistry}. + */ + addList(plugins: Set): void; + + /** + * Returns true if a plugin of the given type is currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + */ + //Class + has(pluginClassName: string): boolean; + + /** + * Returns the instance of a plugin that is currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}, which + * matches the given {@code pluginClass}. + * + *

If no matching plugin is found, {@code null} is returned. + */ + //Class + get(pluginClassName: string): FlutterPlugin; + + /** + * Detaches the plugin of the given type from the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no such plugin exists, this method does nothing. + */ + //Class + remove(pluginClassName: string): void; + + /** + * Detaches the plugins of the given types from the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no such plugins exist, this method does nothing. + */ + //Class + removeList(pluginClassNames: Set): void; + + /** + * Detaches all plugins that are currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no plugins are currently attached, this method does nothing. + */ + removeAll(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets new file mode 100644 index 0000000000000000000000000000000000000000..bd68f68aee68859e0c13b696743c8d9d280b7500 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * {@link io.flutter.embedding.engine.plugins.FlutterPlugin} that is interested in {@link + * ohos.app.ability.UIAbility} lifecycle events related to a {@link + * io.flutter.embedding.engine.FlutterEngine} running within the given {@link ohos.app.ability.UIAbility}. + */ +import { AbilityPluginBinding } from './AbilityPluginBinding'; + +export default interface AbilityAware { + /** + * This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} is now + * associated with an {@link ohos.app.ability.UIAbility}. + * + *

This method can be invoked in 1 of 2 situations: + * + *

    + *
  • This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} was + * just added to a {@link io.flutter.embedding.engine.FlutterEngine} that was already + * connected to a running {@link ohos.app.ability.UIAbility}. + *
  • This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} was + * already added to a {@link io.flutter.embedding.engine.FlutterEngine} and that {@link + * io.flutter.embedding.engine.FlutterEngine} was just connected to an {@link + * ohos.app.ability.UIAbility}. + *
+ * + * The given {@link AbilityPluginBinding} contains {@link ohos.app.ability.UIAbility}-related + * references that an {@code AbilityAware} {@link + * io.flutter.embedding.engine.plugins.FlutterPlugin} may require, such as a reference to the + * actual {@link ohos.app.ability.UIAbility} in question. The {@link AbilityPluginBinding} may be + * referenced until either {@link #onDetachedFromAbilityForConfigChanges()} or {@link + * #onDetachedFromAbility()} is invoked. At the conclusion of either of those methods, the + * binding is no longer valid. Clear any references to the binding or its resources, and do not + * invoke any further methods on the binding or its resources. + */ + onAttachedToAbility(binding: AbilityPluginBinding): void ; + + /** + * This plugin has been detached from an {@link ohos.app.ability.UIAbility}. + * + *

Detachment can occur for a number of reasons. + * + *

    + *
  • The app is no longer visible and the {@link ohos.app.ability.UIAbility} instance has been + * destroyed. + *
  • The {@link io.flutter.embedding.engine.FlutterEngine} that this plugin is connected to + * has been detached from its {@link io.flutter.embedding.android.FlutterView}. + *
  • This {@code AbilityAware} plugin has been removed from its {@link + * io.flutter.embedding.engine.FlutterEngine}. + *
+ * + * By the end of this method, the {@link ohos.app.ability.UIAbility} that was made available in {@link + * #onAttachedToAbility(AbilityPluginBinding)} is no longer valid. Any references to the + * associated {@link ohos.app.ability.UIAbility} or {@link AbilityPluginBinding} should be cleared. + * + *

Any {@code Lifecycle} listeners that were registered in {@link + * #onAttachedToAbility(AbilityPluginBinding)} or {@link + * #onReattachedToAbilityForConfigChanges(AbilityPluginBinding)} should be deregistered here to + * avoid a possible memory leak and other side effects. + */ + onDetachedFromAbility(): void; +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdc25248736f45b41fa4752c386522de4fa3759c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from '../../../ohos/ExclusiveAppComponent'; + +export default interface ActivityControlSurface { + attachToAbility(exclusiveActivity: ExclusiveAppComponent): void; + detachFromAbility(): void; + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; + onWindowFocusChanged(hasFocus: boolean): void; + // onSaveState(reason: AbilityConstant.StateType, wantParam: { [key: string]: Object; }): AbilityConstant.OnSaveResult; + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets new file mode 100644 index 0000000000000000000000000000000000000000..9195e2f8f325596759a756dfdb93dc69a27b3e9e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility' +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export interface AbilityPluginBinding { + getAbility(): UIAbility; + /** + * Adds a listener that is invoked whenever the associated {@link ohos.app.ability.UIAbility}'s {@code + * onNewWant(...)} method is invoked. + */ + addOnNewWantListener(listener: NewWantListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnNewWantListener(NewWantListener)}. + */ + removeOnNewWantListener(listener: NewWantListener): void; + + /** + * Adds a listener that is invoked whenever the associated {@link ohos.app.ability.UIAbility}'s {@code + * windowStageEvent} method is invoked. + */ + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnWindowFocusChangedListener(WindowFocusChangedListener)}. + */ + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; + + /** + * Adds a listener that is invoked when the associated {@code UIAbility} saves + * and restores instance state. + */ + addOnSaveStateListener(listener: OnSaveStateListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnSaveStateListener(OnSaveStateListener)}. + */ + removeOnSaveStateListener(listener: OnSaveStateListener): void; +} + +/** + * Delegate interface for handling new wants on behalf of the main {@link ohos.app.ability.UIAbility}. + */ +export interface NewWantListener { + /** + * @param intent The new want that was started for the UIAbility. + * @return true if the new want has been handled. + */ + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; +} + +/** + * Delegate interface for handling window focus changes on behalf of the main {@link + * ohos.app.ability.UIAbility}. + */ +export interface WindowFocusChangedListener { + onWindowFocusChanged(hasFocus: boolean): void; +} + +export interface OnSaveStateListener { + /** + * Invoked when the associated {@code UIAbility} or {@code Fragment} executes {@link + * Activity#onSaveState(Bundle)}. + */ + // onSaveState(reason: AbilityConstant.StateType, wantParam: { [key: string]: Object; }): AbilityConstant.OnSaveResult; + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets new file mode 100644 index 0000000000000000000000000000000000000000..c7fecd5c1feaeac02f81d95da5a6773f7786b5d1 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + + export interface FlutterUiDisplayListener { + onFlutterUiDisplayed(): void; + + onFlutterUiNoLongerDisplayed(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..ed96f236fb55a878ef4b03766a7751cf389e377a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +import BasicMessageChannel, { MessageHandler, Reply} from '../../../plugin/common/BasicMessageChannel'; +import HashMap from '@ohos.util.HashMap'; +import FlutterNapi, {AccessibilityDelegate} from '../FlutterNapi'; +import { Action } from '../../../view/AccessibilityBridge' +import StandardMessageCodec from '../../../plugin/common/StandardMessageCodec'; + +/** +* 辅助功能channel +*/ +export default class AccessibilityChannel implements MessageHandler{ + private static TAG = "AccessibilityChannel"; + private static CHANNEL_NAME = "flutter/accessibility"; + private channel: BasicMessageChannel; + private flutterNapi: FlutterNapi; + private handler: AccessibilityMessageHandler; + private nextReplyId: number = 1; + + onMessage(message: object, reply: Reply): void { + if (this.handler == null) { + Log.i(AccessibilityChannel.TAG, "NULL"); + reply.reply(null); + return; + } + let annotatedEvent: HashMap = message as HashMap; + let type: string = annotatedEvent.get("type") as string; + let data: HashMap = annotatedEvent.get("data") as HashMap; + + Log.i(AccessibilityChannel.TAG, "Received " + type + " message."); + switch (type) { + case "announce": { + Log.i(AccessibilityChannel.TAG, "Announce"); + let announceMessage: string = data.get("message"); + if (announceMessage != null) { + this.handler.announce(announceMessage); + } + break; + } + case "tap": { + Log.i(AccessibilityChannel.TAG, "Tag"); + let nodeId: number = annotatedEvent.get("nodeId"); + if (nodeId != null) { + this.handler.onTap(nodeId); + } + break; + } + case "longPress": { + Log.i(AccessibilityChannel.TAG, "LongPress"); + let nodeId: number = annotatedEvent.get("nodeId"); + if (nodeId != null) { + this.handler.onLongPress(nodeId); + } + break; + } + case "tooltip": { + Log.i(AccessibilityChannel.TAG, "ToolTip"); + let tooltipMessage: string = data.get("message"); + if (tooltipMessage != null) { + this.handler.onTooltip(tooltipMessage); + } + break; + } + } + reply.reply(null); + } + + constructor(dartExecutor: DartExecutor, flutterNapi: FlutterNapi) { + Log.i(AccessibilityChannel.TAG, "Channel entered"); + this.channel = new BasicMessageChannel(dartExecutor, AccessibilityChannel.CHANNEL_NAME, StandardMessageCodec.INSTANCE); + this.channel.setMessageHandler(this); + this.flutterNapi = flutterNapi; + } + + onOhosAccessibilityEnabled(): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.setSemanticsEnabled(true, replyId); + } + + onOhosAccessibilityFeatures(accessibilityFeatureFlags: number): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.setAccessibilityFeatures(accessibilityFeatureFlags, replyId); + } + + dispatchSemanticsAction(virtualViewId: number, action: Action): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.dispatchSemanticsAction(virtualViewId, action, replyId); + } + + setAccessibilityMessageHandler(handler: AccessibilityMessageHandler): void { + this.handler = handler; + let replyId: number = this.nextReplyId++; + this.flutterNapi.setAccessibilityDelegate(handler, replyId); + } + +} + +interface AccessibilityMessageHandler extends AccessibilityDelegate { + announce(message: string): void; + onTap(nodeId: number): void; + onLongPress(nodeId: number): void; + onTooltip(nodeId: string): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ac0e08bf3da27a8a14a8e83c47099184ba63945 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import { Reply } from '../../../plugin/common/BasicMessageChannel'; +import { Action, Key, KeyEvent } from '@ohos.multimodalInput.keyEvent'; +import Log from '../../../util/Log'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; + +export default class KeyEventChannel { + private static TAG = "KeyEventChannel"; + private static CHANNEL_NAME = "flutter/keyevent"; + private channel : BasicMessageChannel>; + + constructor(binaryMessenger: BinaryMessenger) { + this.channel = new BasicMessageChannel>(binaryMessenger, KeyEventChannel.CHANNEL_NAME, JSONMessageCodec.INSTANCE); + } + + sendFlutterKeyEvent(keyEvent: FlutterKeyEvent, + isKeyUp: boolean, + responseHandler: EventResponseHandler): void { + this.channel.send(this.encodeKeyEvent(keyEvent, isKeyUp), + (message:Map) => { + let isEventHandled = false; + try { + if (message != null) { + isEventHandled = message.get("handled") as boolean; + } + } catch (e) { + Log.e(KeyEventChannel.TAG, "Unable to unpack JSON message: " + e); + } + responseHandler.onFrameworkResponse(isEventHandled); + } + ); + } + + encodeKeyEvent(keyEvent: FlutterKeyEvent, isKeyUp: boolean): Map { + let message: Map = new Map(); + message.set("type", isKeyUp ? "keyup" : "keydown"); + message.set("keymap", "ohos"); + message.set("codePoint", keyEvent.event.unicodeChar); + message.set("keyCode", keyEvent.event.key.code); + message.set("deviceId", keyEvent.event.key.deviceId); + message.set("character", keyEvent.event.key.code.toString()); + message.set("repeatCount", 1); + return message; + } + + +} + +export interface EventResponseHandler { + onFrameworkResponse(isEventHandled: boolean): void; +} + +export class FlutterKeyEvent { + event: KeyEvent; + + constructor( ohosKeyEvent: KeyEvent) { + this.event = ohosKeyEvent; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce5acbdbbae50078e7c339c767a34a178413bf2d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log'; +import StringCodec from '../../../plugin/common/StringCodec'; +import DartExecutor from '../dart/DartExecutor'; +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; + +/** + * 生命周期channel + */ +export default class LifecycleChannel { + private static TAG = "LifecycleChannel"; + private static CHANNEL_NAME = "flutter/lifecycle"; + + // These should stay in sync with the AppLifecycleState enum in the framework. + private static RESUMED = "AppLifecycleState.resumed"; + private static INACTIVE = "AppLifecycleState.inactive"; + private static PAUSED = "AppLifecycleState.paused"; + private static DETACHED = "AppLifecycleState.detached"; + + private lastOhosState = ""; + private lastFlutterState = ""; + private lastFocus = true; + + private channel: BasicMessageChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, LifecycleChannel.CHANNEL_NAME, StringCodec.INSTANCE) + } + + // Called if at least one window in the app has focus. + aWindowIsFocused(): void { + this.sendState(this.lastOhosState, true); + } + + // Called if no windows in the app have focus. + noWindowsAreFocused(): void { + this.sendState(this.lastOhosState, false); + } + + appIsResumed(): void { + this.sendState(LifecycleChannel.RESUMED, this.lastFocus); + } + + appIsInactive(): void { + this.sendState(LifecycleChannel.INACTIVE, this.lastFocus); + } + + appIsPaused(): void { + this.sendState(LifecycleChannel.PAUSED, this.lastFocus); + } + + appIsDetached(): void { + this.sendState(LifecycleChannel.DETACHED, this.lastFocus); + } + + // Here's the state table this implements: + // + // | UIAbility State | Window focused | Flutter state | + // |-----------------|----------------|---------------| + // | onCreate | true | resumed | + // | onCreate | false | inactive | + // | onForeground | true | resumed | + // | onForeground | false | inactive | + // | onBackground | true | paused | + // | onBackground | false | paused | + // | onDestroy | true | detached | + // | onDestroy | false | detached | + + private sendState(state: string, hasFocus: boolean): void { + if (this.lastOhosState == state && hasFocus == this.lastFocus) { + // No inputs changed, so Flutter state could not have changed. + return; + } + let newState: string; + if (state == LifecycleChannel.RESUMED) { + newState = hasFocus ? LifecycleChannel.RESUMED : LifecycleChannel.INACTIVE; + } else { + newState = state; + } + // Keep the last reported values for future updates. + this.lastOhosState = state; + this.lastFocus = hasFocus; + if (newState == this.lastFlutterState) { + // No change in the resulting Flutter state, so don't report anything. + return; + } + Log.i(LifecycleChannel.TAG, "Sending " + newState + " message."); + this.channel.send(newState); + this.lastFlutterState = newState; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4b5b6cf7b8868145424897851dd734d7eff5b6a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import DartExecutor from '../dart/DartExecutor'; +import MethodChannel, { MethodCallHandler, MethodResult} from '../../../plugin/common/MethodChannel'; +import MethodCall from '../../../plugin/common/MethodCall'; +import List from '@ohos.util.List'; +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import intl from '@ohos.intl'; +import Log from '../../../util/Log'; + +const TAG = "LocalizationChannel"; +export default class LocalizationChannel implements MethodCallHandler{ + private static TAG = "LocalizationChannel"; + private static CHANNEL_NAME = "flutter/localization"; + private channel: MethodChannel; + private localizationMessageHandler: LocalizationMessageHandler; + + onMethodCall(call: MethodCall, result: MethodResult) :void { + if (this.localizationMessageHandler == null) { + Log.e(TAG, "localizationMessageHandler is null"); + return; + } + let method: string = call.method; + switch (method) { + case "Localization.getStringResource": { + Log.i(TAG, "Localization.getStringResource enter"); + let key: string = call.argument("key"); + let localeString: string = null; + if (call.hasArgument("locale")) { + localeString = call.argument("locale"); + } + result.success(this.localizationMessageHandler.getStringResource(key, localeString)); + break; + } + default: { + result.notImplemented(); + break; + } + } + } + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, LocalizationChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + this.channel.setMethodCallHandler(this); + } + + setLocalizationMessageHandler(localizationMessageHandler: LocalizationMessageHandler): void { + this.localizationMessageHandler = localizationMessageHandler; + } + + sendLocales(locales: Array): void { + this.channel.invokeMethod("setLocale", locales); + } +} + +export interface LocalizationMessageHandler { + getStringResource(key: string, local: string); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..210a7510a478d350cd38e89d7826e3a53290dfa8 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG:string = 'MouseCursorChannel' + +export default class MouseCursorChannel implements MethodCallHandler { + public channel: MethodChannel; + + private mouseCursorMethodHandler: MouseCursorMethodHandler; + + onMethodCall(call: MethodCall, result: MethodResult): void { + if (this.mouseCursorMethodHandler === null) { + // if no explicit mouseCursorMethodHandler has been registered then we don't + // need to formed this call to an API. Return + Log.e(TAG, "mouseCursorMethodHandler is null") + return; + } + + let method: string = call.method; + Log.i(TAG, "Received '" + method + "' message."); + try { + // More methods are expected to be added here, hence the switch. + switch (method) { + case "activateSystemCursor": + let argument: HashMap = call.args; + let kind: string = argument.get("kind"); + try { + this.mouseCursorMethodHandler.activateSystemCursor(kind); + } catch (err) { + result.error("error", "Error when setting cursors: " + JSON.stringify(err), null); + break; + } + result.success(true); + break; + default: + break; + } + } catch (error) { + result.error("error", "UnHandled error: " + JSON.stringify(error), null) + } + } + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/mousecursor", StandardMethodCodec.INSTANCE); + this.channel.setMethodCallHandler(this); + } + + /** + * Sets the {@link MouseCursorMethodHandler} which receives all events and requests that are + * parsed from the underlying platform channel. + * @param mouseCursorMethodHandler + */ + public setMethodHandler(mouseCursorMethodHandler: MouseCursorMethodHandler): void { + this.mouseCursorMethodHandler = mouseCursorMethodHandler; + } + + public synthesizeMethodCall(call: MethodCall, result: MethodResult): void { + this.onMethodCall(call, result); + } +} + +export interface MouseCursorMethodHandler { + // Called when the pointer should start displaying a system mouse cursor + // specified by {@code shapeCode}. + activateSystemCursor(kind: String): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ebcb6926eb490ed2ee21cb8927e5ed2a202632 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +export default class NavigationChannel { + private static TAG = "NavigationChannel"; + private channel: MethodChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/navigation", JSONMethodCodec.INSTANCE); + // Provide a default handler that returns an empty response to any messages + // on this channel. + this.channel.setMethodCallHandler(new NavigationCallback()); + } + + setInitialRoute(initialRoute: string): void { + Log.i(NavigationChannel.TAG, "Sending message to set initial route to '" + initialRoute + "'"); + this.channel.invokeMethod("setInitialRoute", initialRoute); + } + + pushRoute(route: string): void { + Log.i(NavigationChannel.TAG, "Sending message to push route '" + route + "'"); + this.channel.invokeMethod("pushRoute", route); + } + + pushRouteInformation(route: string): void { + Log.i(NavigationChannel.TAG, "Sending message to push route information '" + route + "'"); + this.channel.invokeMethod("pushRouteInformation", new Map().set("location", route) ); + } + + popRoute(): void { + Log.i(NavigationChannel.TAG, "Sending message to pop route."); + this.channel.invokeMethod("popRoute", null); + } + + setMethodCallHandler(handler: MethodCallHandler) { + this.channel.setMethodCallHandler(handler); + } +} + +class NavigationCallback implements MethodCallHandler { + onMethodCall(call: MethodCall, result: MethodResult) { + result.success(null); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..20e8db4b44690fd0e2bafbde4044a1f0724fba7f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets @@ -0,0 +1,505 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +import pasteboard from '@ohos.pasteboard'; +import bundleManager from '@ohos.bundle.bundleManager'; +import window from '@ohos.window'; + +export default class PlatformChannel { + private static TAG = "PlatformChannel"; + private static CHANNEL_NAME = "flutter/platform"; + channel: MethodChannel; + platformMessageHandler: PlatformMessageHandler; + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, PlatformChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + let callback = new PlatformMethodCallback(); + callback.platform = this; + this.channel.setMethodCallHandler(callback); + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.platformMessageHandler = platformMessageHandler; + } + + systemChromeChanged(overlaysAreVisible: boolean): void { + Log.d(PlatformChannel.TAG, "Sending 'systemUIChange' message."); + this.channel.invokeMethod("SystemChrome.systemUIChange", [overlaysAreVisible]); + } + + decodeOrientations(encodedOrientations: string[]): number { + let requestedOrientation = 0x00; + let firstRequestedOrientation = 0x00; + for(let index = 0; index< encodedOrientations.length; index += 1) { + let encodedOrientation = encodedOrientations[index]; + Log.d(PlatformChannel.TAG,"encodedOrientation[" + index + "]: "+encodedOrientation); + let orientation = this.getDeviceOrientationFromValue(encodedOrientation); + switch (orientation) { + case DeviceOrientation.PORTRAIT_UP: + requestedOrientation |= 0x01; + break; + case DeviceOrientation.PORTRAIT_DOWN: + requestedOrientation |= 0x04; + break; + case DeviceOrientation.LANDSCAPE_LEFT: + requestedOrientation |= 0x02; + break; + case DeviceOrientation.LANDSCAPE_RIGHT: + requestedOrientation |= 0x08; + break; + } + if (firstRequestedOrientation == 0x00) { + firstRequestedOrientation = requestedOrientation; + } + } + + switch (requestedOrientation) { + case 0x00: + return window.Orientation.UNSPECIFIED; + case 0x01: + return window.Orientation.PORTRAIT; + case 0x02: + return window.Orientation.LANDSCAPE; + case 0x03: + case 0x04: + return window.Orientation.PORTRAIT_INVERTED; + case 0x05: + return window.Orientation.AUTO_ROTATION_PORTRAIT; + case 0x06: + case 0x07: + case 0x08: + return window.Orientation.LANDSCAPE_INVERTED; + case 0x09: + case 0x0a: + return window.Orientation.AUTO_ROTATION_LANDSCAPE; + case 0x0b: + return window.Orientation.LOCKED; + case 0x0c: + case 0x0d: + case 0x0e: + switch (firstRequestedOrientation) { + case 0x01: + return bundleManager.DisplayOrientation.PORTRAIT; + case 0x02: + return bundleManager.DisplayOrientation.LANDSCAPE; + case 0x04: + return bundleManager.DisplayOrientation.PORTRAIT_INVERTED; + case 0x08: + return bundleManager.DisplayOrientation.LANDSCAPE_INVERTED; + } + case 0x0f: + } + return bundleManager.DisplayOrientation.PORTRAIT; + } + + getFeedbackTypeFromValue(encodedName: string): HapticFeedbackType { + if (encodedName == null) { + return HapticFeedbackType.STANDARD; + } + let feedbackTypes: string[] = [ + HapticFeedbackType.STANDARD, + HapticFeedbackType.LIGHT_IMPACT, + HapticFeedbackType.MEDIUM_IMPACT, + HapticFeedbackType.HEAVY_IMPACT, + HapticFeedbackType.SELECTION_CLICK + ]; + for (let i = 0; i < feedbackTypes.length; i++) { + let feedbackType: string = feedbackTypes[i]; + if ( + (HapticFeedbackType[feedbackType] == encodedName) || + (HapticFeedbackType[feedbackType] == null && encodedName == null) + ) { + return HapticFeedbackType[feedbackType]; + } + } + Log.e(PlatformChannel.TAG, "No such HapticFeedbackType:" + encodedName); + } + + getClipboardContentFormatFromValue(encodedName: string): ClipboardContentFormat { + let clipboardFormats : string[]= [ClipboardContentFormat.PLAIN_TEXT]; + for (let i = 0; i < clipboardFormats.length; i++) { + let format = clipboardFormats[i]; + if (ClipboardContentFormat[format] === encodedName) { + return ClipboardContentFormat[format]; + } + } + } + getSystemUiOverlayFromValue(encodedName: string): SystemUiOverlay { + let systemUiOverlays : string[] = [SystemUiOverlay.TOP_OVERLAYS, SystemUiOverlay.BOTTOM_OVERLAYS]; + for (let i = 0; i < systemUiOverlays.length; i++) { + let overlay = systemUiOverlays[i]; + if (SystemUiOverlay[overlay] === encodedName) { + return SystemUiOverlay[overlay]; + } + } + throw new Error("No such SystemUiOverlay: " + encodedName); + } + + getSystemUiModeFromValue(encodedName: string): SystemUiMode { + let systemUiModes : string[] = [ + SystemUiMode.LEAN_BACK, SystemUiMode.IMMERSIVE, + SystemUiMode.IMMERSIVE_STICKY, SystemUiMode.EDGE_TO_EDGE + ]; + for (let i = 0; i < systemUiModes.length; i++) { + let mode = systemUiModes[i]; + if (SystemUiMode[mode] === encodedName) { + return SystemUiMode[mode]; + } + } + throw new Error("No such SystemUiOverlay: " + encodedName); + } + + getBrightnessFromValue(encodedName: string): Brightness { + let brightnesses : string[] = [Brightness.LIGHT, Brightness.DARK]; + for (let i = 0; i < brightnesses.length; i++) { + let brightness = brightnesses[i]; + if (Brightness[brightness] === encodedName) { + return Brightness[brightness]; + } + } + throw new Error("No such Brightness: " + encodedName); + } + + getDeviceOrientationFromValue(encodedName: string): DeviceOrientation { + let deviceOrientations: string[] = [ + DeviceOrientation.PORTRAIT_UP, DeviceOrientation.PORTRAIT_DOWN, + DeviceOrientation.LANDSCAPE_LEFT, DeviceOrientation.LANDSCAPE_RIGHT + ]; + for (let i = 0; i < deviceOrientations.length; i++) { + let orientation = deviceOrientations[i]; + if (DeviceOrientation[orientation] === encodedName) { + return DeviceOrientation[orientation]; + } + } + throw new Error("No such DeviceOrientation: " + encodedName); + } + +} + +export enum HapticFeedbackType { + STANDARD = "STANDARD", + LIGHT_IMPACT = "HapticFeedbackType.lightImpact", + MEDIUM_IMPACT = "HapticFeedbackType.mediumImpact", + HEAVY_IMPACT = "HapticFeedbackType.heavyImpact", + SELECTION_CLICK = "HapticFeedbackType.selectionClick" +} + +export interface PlatformMessageHandler { + playSystemSound(soundType: SoundType): void; + + vibrateHapticFeedback(feedbackType: HapticFeedbackType): void; + + setPreferredOrientations(ohosOrientation: number): void; + + setApplicationSwitcherDescription(description: AppSwitcherDescription): void; + + showSystemOverlays(overlays: SystemUiOverlay[]): void; + + showSystemUiMode(mode: SystemUiMode): void; + + setSystemUiChangeListener(): void; + + restoreSystemUiOverlays(): void; + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle): void; + + popSystemNavigator(): void; + + getClipboardData(format: ClipboardContentFormat): string; + + setClipboardData(text: string): void; + + clipboardHasStrings(): boolean; +} + +export enum ClipboardContentFormat { + PLAIN_TEXT = "text/plain", +} + +export enum SoundType { + CLICK = "SystemSoundType.click", + ALERT = "SystemSoundType.alert", +} + +export class AppSwitcherDescription { + public readonly color: number; + public readonly label: string; + + constructor(color: number, label: string) { + this.color = color; + this.label = label; + } +} + +export enum SystemUiOverlay { + TOP_OVERLAYS = "SystemUiOverlay.top", + BOTTOM_OVERLAYS = "SystemUiOverlay.bottom", +} + +export enum SystemUiMode { + LEAN_BACK = "SystemUiMode.leanBack", + IMMERSIVE = "SystemUiMode.immersive", + IMMERSIVE_STICKY = "SystemUiMode.immersiveSticky", + EDGE_TO_EDGE = "SystemUiMode.edgeToEdge", +} + +export enum Brightness { + LIGHT = "Brightness.light", + DARK = "Brightness.dark", +} + +export class SystemChromeStyle { + public readonly statusBarColor: number | null; + public readonly statusBarIconBrightness: Brightness | null; + public readonly systemStatusBarContrastEnforced: boolean | null; + public readonly systemNavigationBarColor: number | null; + public readonly systemNavigationBarIconBrightness: Brightness | null; + public readonly systemNavigationBarDividerColor: number | null; + public readonly systemNavigationBarContrastEnforced: boolean | null; + + constructor(statusBarColor: number | null, + statusBarIconBrightness: Brightness | null, + systemStatusBarContrastEnforced: boolean | null, + systemNavigationBarColor: number | null, + systemNavigationBarIconBrightness: Brightness | null, + systemNavigationBarDividerColor: number | null, + systemNavigationBarContrastEnforced: boolean | null) { + this.statusBarColor = statusBarColor; + this.statusBarIconBrightness = statusBarIconBrightness; + this.systemStatusBarContrastEnforced = systemStatusBarContrastEnforced; + this.systemNavigationBarColor = systemNavigationBarColor; + this.systemNavigationBarIconBrightness = systemNavigationBarIconBrightness; + this.systemNavigationBarDividerColor = systemNavigationBarDividerColor; + this.systemNavigationBarContrastEnforced = systemNavigationBarContrastEnforced; + } +} + +enum DeviceOrientation { + PORTRAIT_UP = "DeviceOrientation.portraitUp", + PORTRAIT_DOWN = "DeviceOrientation.portraitDown", + LANDSCAPE_LEFT = "DeviceOrientation.landscapeLeft", + LANDSCAPE_RIGHT = "DeviceOrientation.landscapeRight", +} + +class PlatformMethodCallback implements MethodCallHandler { + private static TAG = "PlatformMethodCallback" + platform: PlatformChannel; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.platform.platformMessageHandler == null) { + Log.w(PlatformMethodCallback.TAG, "platformMessageHandler is null"); + return; + } + + let method: string = call.method; + let args: ESObject = call.args; + Log.d(PlatformMethodCallback.TAG, "Received '" + method + "' message."); + try { + switch (method) { + case "SystemSound.play": + break; + case "HapticFeedback.vibrate": + try { + Log.d(PlatformMethodCallback.TAG, "HapticFeedback: " + args as string); + let feedbackType: HapticFeedbackType = this.platform.getFeedbackTypeFromValue(args as string); + this.platform.platformMessageHandler.vibrateHapticFeedback(feedbackType); + result.success(null); + } catch (e) { + Log.e(PlatformMethodCallback.TAG, "HapticFeedback.vibrate error:" + JSON.stringify(e)); + } + break; + case "SystemChrome.setPreferredOrientations": + Log.d(PlatformMethodCallback.TAG, "setPreferredOrientations: " + JSON.stringify(args)); + try { + let ohosOrientation = this.platform.decodeOrientations(args as string[]); + this.platform.platformMessageHandler.setPreferredOrientations(ohosOrientation); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setPreferredOrientations err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + + break; + case "SystemChrome.setApplicationSwitcherDescription": + Log.d(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription: " + JSON.stringify(args)); + break; + case "SystemChrome.setEnabledSystemUIOverlays": + try { + let overlays: SystemUiOverlay[] = this.decodeSystemUiOverlays(args); + Log.d(PlatformMethodCallback.TAG, "overlays: " + overlays); + this.platform.platformMessageHandler.showSystemOverlays(overlays); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIOverlays err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemChrome.setEnabledSystemUIMode": + try { + Log.d(PlatformMethodCallback.TAG, "setEnabledSystemUIMode args:" + args as string); + let mode: SystemUiMode = this.decodeSystemUiMode(args as string) + this.platform.platformMessageHandler.showSystemUiMode(mode); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIMode err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemChrome.setSystemUIChangeListener": + this.platform.platformMessageHandler.setSystemUiChangeListener(); + result.success(null); + break; + case "SystemChrome.restoreSystemUIOverlays": + this.platform.platformMessageHandler.restoreSystemUiOverlays(); + result.success(null); + break; + case "SystemChrome.setSystemUIOverlayStyle": + try { + Log.d(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle asrgs: " + JSON.stringify(args)); + let systemChromeStyle: SystemChromeStyle = this.decodeSystemChromeStyle(args); + this.platform.platformMessageHandler.setSystemUiOverlayStyle(systemChromeStyle); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemNavigator.pop": + this.platform.platformMessageHandler.popSystemNavigator(); + result.success(null); + break; + case "Clipboard.getData": + let pasteBoard = pasteboard.getSystemPasteboard(); + pasteBoard.getData().then((pasteData) => { + let text = pasteData.getPrimaryText(); + let response: ESObject = new Map().set("text", ""); + response.text = text; + result.success(response); + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "Failed to get PasteData. Cause: " + JSON.stringify(err)); + }); + break; + case "Clipboard.setData": + let clipboardContent: string = args.text; + this.platform.platformMessageHandler.setClipboardData(clipboardContent); + result.success(null); + break; + case "Clipboard.hasStrings": + let hasStrings: boolean = false; + let response: ESObject = new Map().set("value", false); + let systemPasteboard = pasteboard.getSystemPasteboard(); + systemPasteboard.hasData().then((hasData) => { + if (!hasData) { + response.value = hasData; + result.success(response); + } + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "systemPasteboard.hasData err: " + JSON.stringify(err)); + }) + systemPasteboard.getData().then((pasteData) => { + hasStrings = pasteData.hasType(pasteboard.MIMETYPE_TEXT_PLAIN); + response.value = hasStrings; + result.success(response); + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "getData err: " + JSON.stringify(err)); + }) + break; + default: + result.notImplemented(); + break; + } + } catch (e) { + result.error("error", JSON.stringify(e), null); + } + } + + private decodeSystemUiOverlays(encodedSystemUiOverlay: string[]): SystemUiOverlay[] { + let overlays: SystemUiOverlay[] = []; + for(let i = 0; i < encodedSystemUiOverlay.length; i++) { + const encodedOverlay = encodedSystemUiOverlay[i]; + const overlay = this.platform.getSystemUiOverlayFromValue(encodedOverlay); + switch (overlay) { + case SystemUiOverlay.TOP_OVERLAYS: + overlays.push(SystemUiOverlay.TOP_OVERLAYS); + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + overlays.push(SystemUiOverlay.BOTTOM_OVERLAYS); + break; + } + } + return overlays; + } + + private decodeSystemUiMode(encodedSystemUiMode: string): SystemUiMode { + let mode: SystemUiMode = this.platform.getSystemUiModeFromValue(encodedSystemUiMode); + switch (mode) { + case SystemUiMode.LEAN_BACK: + return SystemUiMode.LEAN_BACK; + case SystemUiMode.IMMERSIVE: + return SystemUiMode.IMMERSIVE; + case SystemUiMode.IMMERSIVE_STICKY: + return SystemUiMode.IMMERSIVE_STICKY; + case SystemUiMode.EDGE_TO_EDGE: + default: + return SystemUiMode.EDGE_TO_EDGE; + } + } + + private decodeSystemChromeStyle(encodedStyle: ESObject): SystemChromeStyle { + let statusBarColor: number = null; + let statusBarIconBrightness: Brightness = null; + let systemStatusBarContrastEnforced: boolean = null; + let systemNavigationBarColor: number = null; + let systemNavigationBarIconBrightness: Brightness = null; + let systemNavigationBarDividerColor: number = null; + let systemNavigationBarContrastEnforced: boolean = null; + if(encodedStyle.statusBarColor != null) { + statusBarColor = encodedStyle.statusBarColor as number; + } + if(encodedStyle.statusBarIconBrightness != null) { + statusBarIconBrightness = + this.platform.getBrightnessFromValue(encodedStyle.statusBarIconBrightness as string); + } + if(encodedStyle.systemStatusBarContrastEnforced != null) { + systemStatusBarContrastEnforced = encodedStyle.systemStatusBarContrastEnforced as boolean; + } + if(encodedStyle.systemNavigationBarColor != null) { + systemNavigationBarColor = encodedStyle.systemNavigationBarColor as number; + } + if(encodedStyle.systemNavigationBarIconBrightness != null) { + systemNavigationBarIconBrightness = + this.platform.getBrightnessFromValue(encodedStyle.systemNavigationBarIconBrightness as string); + } + if(encodedStyle.systemNavigationBarDividerColor != null) { + systemNavigationBarDividerColor = encodedStyle.systemNavigationBarDividerColor as number; + } + if(encodedStyle.systemNavigationBarContrastEnforced != null) { + systemNavigationBarContrastEnforced = encodedStyle.systemNavigationBarContrastEnforced as boolean; + } + return new SystemChromeStyle( + statusBarColor, + statusBarIconBrightness, + systemStatusBarContrastEnforced, + systemNavigationBarColor, + systemNavigationBarIconBrightness, + systemNavigationBarDividerColor, + systemNavigationBarContrastEnforced + ); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..564a6df4c4d10c0bdd9dfe22a0b5ec2f3f8e9d5e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets @@ -0,0 +1,551 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import { ByteBuffer } from '../../../util/ByteBuffer'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG = "PlatformViewsChannel"; +const NON_TEXTURE_FALLBACK = -2; +export default class PlatformViewsChannel { + private channel: MethodChannel; + private handler: PlatformViewsHandler; + private parsingHandler = new ParsingCallback(); + + /** + * Constructs a {@code PlatformViewsChannel} that connects Android to the Dart code running in + * {@code dartExecutor}. + * + *

The given {@code dartExecutor} is permitted to be idle or executing code. + * + *

See {@link DartExecutor}. + */ + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/platform_views", StandardMethodCodec.INSTANCE); + this.parsingHandler.platformChannel = this; + this.channel.setMethodCallHandler(this.parsingHandler); + } + + /** + * Sets the {@link PlatformViewsHandler} which receives all events and requests that are parsed + * from the underlying platform views channel. + */ + public setPlatformViewsHandler(handler: PlatformViewsHandler): void { + this.handler = handler; + this.parsingHandler.handler = handler; + } + + public invokeViewFocused(viewId: number): void { + if (this.channel == null) { + return; + } + this.channel.invokeMethod("viewFocused", viewId); + } + + create(call: MethodCall, result: MethodResult): void { + const createArgs: Map = call.args; + const usesPlatformViewLayer: boolean = createArgs.has("hybrid") && createArgs.get("hybrid") as boolean; + const additionalParams: ByteBuffer = createArgs.has("params") ? createArgs.get("params") : null; + + let direction: Direction = Direction.Ltr; + if (createArgs.get("direction") == 0) { + direction = Direction.Ltr; + } else if (createArgs.get("direction") == 1) { + direction = Direction.Rtl; + } + + try { + if (usesPlatformViewLayer) { + const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( + createArgs.get("id"), + createArgs.get("viewType"), + 0, + 0, + 0, + 0, + direction, + additionalParams, + RequestedDisplayMode.HYBRID_ONLY + ); + this.handler.createForPlatformViewLayer(request); + result.success(null); + } else { + const hybridFallback: boolean = createArgs.has("hybridFallback") && createArgs.get("hybridFallback"); + const displayMode: RequestedDisplayMode = + hybridFallback ? RequestedDisplayMode.TEXTURE_WITH_HYBRID_FALLBACK + : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; + const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( + createArgs.get("id"), + createArgs.get("viewType"), + createArgs.has("top") ? createArgs.get("top") : 0.0, + createArgs.has("left") ? createArgs.get("left") : 0.0, + createArgs.get("width"), + createArgs.get("height"), + direction, + additionalParams, + displayMode + ); + + Log.i(TAG, `Create texture param id:${request.viewId}, + type:${request.viewType}, + w:${request.logicalWidth}, + h:${request.logicalHeight}, + l:${request.logicalLeft}, + t:${request.logicalTop}, + d:${request.direction}`); + + const textureId = this.handler.createForTextureLayer(request); + if (textureId == NON_TEXTURE_FALLBACK) { + if (!hybridFallback) { + throw new Error( + "Platform view attempted to fall back to hybrid mode when not requested."); + } + + // A fallback to hybrid mode is indicated with a null texture ID. + result.success(null); + } else { + result.success(textureId); + } + } + } catch (err) { + Log.e(TAG, "create failed" + err); + result.error("error", err, null); + } + } + + dispose(call: MethodCall, result: MethodResult): void { + const disposeArgs: Map = call.args; + const viewId: number = disposeArgs.get("id"); + try { + this.handler.dispose(viewId); + result.success(null); + } catch (err) { + Log.e(TAG, "dispose failed", err); + result.error("error", err, null); + } + } + + resize(call: MethodCall, result: MethodResult): void { + const resizeArgs: Map = call.args; + const resizeRequest: PlatformViewResizeRequest = new PlatformViewResizeRequest( + resizeArgs.get("id"), + resizeArgs.get("width"), + resizeArgs.get("height") + ); + try { + let resizeCallback = new ResizeCallback(); + resizeCallback.result = result; + this.handler.resize(resizeRequest, resizeCallback); + } catch (err) { + Log.e(TAG, "resize failed", err); + result.error("error", err, null); + } + } + + offset(call: MethodCall, result: MethodResult): void { + const offsetArgs: Map = call.args; + try { + this.handler.offset( + offsetArgs.get("id"), + offsetArgs.get("top"), + offsetArgs.get("left")); + result.success(null); + } catch (err) { + Log.e(TAG, "offset failed", err); + result.error("error", err, null); + } + } + + touch(call: MethodCall, result: MethodResult): void { + const args: Array = call.args; + let index = 0; + const touch: PlatformViewTouch = new PlatformViewTouch( + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index] + ); + + try { + this.handler.onTouch(touch); + result.success(null); + } catch (err) { + Log.e(TAG, "offset failed", err); + result.error("error", err, null); + } + } + + setDirection(call: MethodCall, result: MethodResult): void { + const setDirectionArgs: Map = call.args; + const newDirectionViewId: number = setDirectionArgs.get("id"); + const direction: number = setDirectionArgs.get("direction"); + + try { + this.handler.setDirection(newDirectionViewId, direction); + result.success(null); + } catch (err) { + Log.e(TAG, "setDirection failed", err); + result.error("error", err, null); + } + } + + clearFocus(call: MethodCall, result: MethodResult): void { + const viewId: number = call.args; + try { + this.handler.clearFocus(viewId); + result.success(null); + } catch (err) { + Log.e(TAG, "clearFocus failed", err); + result.error("error", err, null); + } + } + + synchronizeToNativeViewHierarchy(call: MethodCall, result: MethodResult): void { + const yes: boolean = call.args; + try { + this.handler.synchronizeToNativeViewHierarchy(yes); + result.success(null); + } catch (err) { + Log.e(TAG, "synchronizeToNativeViewHierarchy failed", err); + result.error("error", err, null); + } + } +} + +/** + * Handler that receives platform view messages sent from Flutter to Ohos through a given + * {@link PlatformViewsChannel}. + * + *

To register a {@code PlatformViewsHandler} with a {@link PlatformViewsChannel}, see {@link + * PlatformViewsChannel#setPlatformViewsHandler(PlatformViewsHandler)}. + */ +export interface PlatformViewsHandler { + /* + * The ID returned by {@code createForTextureLayer} to indicate that the requested texture mode + * was not available and the view creation fell back to {@code PlatformViewLayer} mode. + * + * This can only be returned if the {@link PlatformViewCreationRequest} sets + * {@code TEXTURE_WITH_HYBRID_FALLBACK} as the requested display mode. + */ + + /** + * The Flutter application would like to display a new Ohos {@code View}, i.e., platform + * view. + * + *

The Ohos View is added to the view hierarchy. This view is rendered in the Flutter + * framework by a PlatformViewLayer. + * + * @param request The metadata sent from the framework. + */ + createForPlatformViewLayer(request: PlatformViewCreationRequest): void; + + /** + * The Flutter application would like to display a new Android {@code View}, i.e., platform + * view. + * + *

The Android View is added to the view hierarchy. This view is rendered in the Flutter + * framework by a TextureLayer. + * + * @param request The metadata sent from the framework. + * @return The texture ID. + */ + createForTextureLayer(request: PlatformViewCreationRequest): number; + + /** The Flutter application would like to dispose of an existing Android {@code View}. */ + dispose(viewId: number): void; + + /** + * The Flutter application would like to resize an existing Android {@code View}. + * + * @param request The request to resize the platform view. + * @param onComplete Once the resize is completed, this is the handler to notify the size of the + * platform view buffer. + */ + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void; + + /** + * The Flutter application would like to change the offset of an existing Android {@code View}. + */ + offset(viewId: number, top: number, left: number): void; + + /** + * The user touched a platform view within Flutter. + * + *

Touch data is reported in {@code touch}. + */ + onTouch(touch: PlatformViewTouch): void; + + /** + * The Flutter application would like to change the layout direction of an existing Android + * {@code View}, i.e., platform view. + */ + setDirection(viewId: number, direction: number): void; + + /** Clears the focus from the platform view with a give id if it is currently focused. */ + clearFocus(viewId: number): void; + + /** + * Whether the render surface of {@code FlutterView} should be converted to a {@code + * FlutterImageView} when a {@code PlatformView} is added. + * + *

This is done to syncronize the rendering of the PlatformView and the FlutterView. Defaults + * to true. + */ + synchronizeToNativeViewHierarchy(yes: boolean): void; +} + +/** Platform view display modes that can be requested at creation time. */ +enum RequestedDisplayMode { + /** Use Texture Layer if possible, falling back to Virtual Display if not. */ + TEXTURE_WITH_VIRTUAL_FALLBACK, + /** Use Texture Layer if possible, falling back to Hybrid Composition if not. */ + TEXTURE_WITH_HYBRID_FALLBACK, + /** Use Hybrid Composition in all cases. */ + HYBRID_ONLY, +} + +/** Request sent from Flutter to create a new platform view. */ +export class PlatformViewCreationRequest { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The type of view to create for this platform view. */ + public viewType: string; + + /** The density independent width to display the platform view. */ + public logicalWidth: number; + + /** The density independent height to display the platform view. */ + public logicalHeight: number; + + /** The density independent top position to display the platform view. */ + public logicalTop: number; + + /** The density independent left position to display the platform view. */ + public logicalLeft: number; + + /** + * The layout direction of the new platform view. + */ + public direction: number; + public displayMode: RequestedDisplayMode; + + /** Custom parameters that are unique to the desired platform view. */ + public params: ByteBuffer; + + constructor(viewId: number, viewType: string, logicalTop: number, logicalLeft: number, logicalWidth: number, + logicalHeight: number, direction: Direction, params: ByteBuffer, displayMode?: RequestedDisplayMode) { + this.viewId = viewId; + this.viewType = viewType; + this.logicalTop = logicalTop; + this.logicalLeft = logicalLeft; + this.logicalWidth = logicalWidth; + this.logicalHeight = logicalHeight; + this.direction = direction; + this.displayMode = displayMode ? displayMode : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; + this.params = params; + } +} + +/** Request sent from Flutter to resize a platform view. */ +export class PlatformViewResizeRequest { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The new density independent width to display the platform view. */ + public newLogicalWidth: number; + + /** The new density independent height to display the platform view. */ + public newLogicalHeight: number; + + constructor(viewId: number, newLogicalWidth: number, newLogicalHeight: number) { + this.viewId = viewId; + this.newLogicalWidth = newLogicalWidth; + this.newLogicalHeight = newLogicalHeight; + } +} + +/** The platform view buffer size. */ +export class PlatformViewBufferSize { + /** The width of the screen buffer. */ + public width: number; + + /** The height of the screen buffer. */ + public height: number; + + constructor(width: number, height: number) { + this.width = width; + this.height = height; + } +} + +/** Allows to notify when a platform view buffer has been resized. */ +export abstract class PlatformViewBufferResized { + abstract run(bufferSize: PlatformViewBufferSize): void; +} + +/** The state of a touch event in Flutter within a platform view. */ +export class PlatformViewTouch { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The amount of time that the touch has been pressed. */ + public downTime: number; + + public eventTime: number; + + public action: number; + + /** The number of pointers (e.g, fingers) involved in the touch event. */ + public pointerCount: number; + + /** Properties for each pointer, encoded in a raw format. */ + public rawPointerPropertiesList: ESObject; + + /** Coordinates for each pointer, encoded in a raw format. */ + public rawPointerCoords: ESObject; + + public metaState: number; + + public buttonState: number; + + /** Coordinate precision along the x-axis. */ + public xPrecision: number; + + /** Coordinate precision along the y-axis. */ + public yPrecision: number; + + public deviceId: number; + + public edgeFlags: number; + + public source: number; + + public flags: number; + + public motionEventId: number; + + constructor(viewId: number, + downTime: number, + eventTime: number, + action: number, + pointerCount: number, + rawPointerPropertiesList: ESObject, + rawPointerCoords: ESObject, + metaState: number, + buttonState: number, + xPrecision: number, + yPrecision: number, + deviceId: number, + edgeFlags: number, + source: number, + flags: number, + motionEventId: number) { + this.viewId = viewId; + this.downTime = downTime; + this.eventTime = eventTime; + this.action = action; + this.pointerCount = pointerCount; + this.rawPointerPropertiesList = rawPointerPropertiesList; + this.rawPointerCoords = rawPointerCoords; + this.metaState = metaState; + this.buttonState = buttonState; + this.xPrecision = xPrecision; + this.yPrecision = yPrecision; + this.deviceId = deviceId; + this.edgeFlags = edgeFlags; + this.source = source; + this.flags = flags; + this.motionEventId = motionEventId; + } +} + +class ParsingCallback implements MethodCallHandler { + platformChannel : PlatformViewsChannel; + handler: PlatformViewsHandler; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.handler == null) { + return; + } + + Log.i(TAG, "Received '" + call.method + "' message."); + switch (call.method) { + case "create": { + this.platformChannel.create(call, result); + break; + } + case "dispose": { + this.platformChannel.dispose(call, result); + break; + } + case "resize": { + this.platformChannel.resize(call, result); + break; + } + case "offset": { + this.platformChannel.offset(call, result); + break; + } + case "touch": { + this.platformChannel.touch(call, result); + break; + } + case "setDirection": { + this.platformChannel.setDirection(call, result); + break; + } + case "clearFocus": { + this.platformChannel.clearFocus(call, result); + break; + } + case "synchronizeToNativeViewHierarchy": { + this.platformChannel.synchronizeToNativeViewHierarchy(call, result); + break; + } + default: + result.notImplemented(); + } + } +} + +class ResizeCallback extends PlatformViewBufferResized { + result : MethodResult; + run(bufferSize: PlatformViewBufferSize) { + if (bufferSize == null) { + this.result.error("error", "Failed to resize the platform view", null); + } else { + const response: Map = new Map(); + response.set("width", bufferSize.width); + response.set("height", bufferSize.height); + this.result.success(response); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcf53050d567f4fc61237845d4019c669873540c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +/** + * System channel to exchange restoration data between framework and engine. + * + *

The engine can obtain the current restoration data from the framework via this channel to + * store it on disk and - when the app is relaunched - provide the stored data back to the framework + * to recreate the original state of the app. + * + *

The channel can be configured to delay responding to the framework's request for restoration + * data via {@code waitForRestorationData} until the engine-side has provided the data. This is + * useful when the engine is pre-warmed at a point in the application's life cycle where the + * restoration data is not available yet. For example, if the engine is pre-warmed as part of the + * Application before an Activity is created, this flag should be set to true because Android will + * only provide the restoration data to the Activity during the onCreate callback. + * + *

The current restoration data provided by the framework can be read via {@code + * getRestorationData()}. + */ +export default class RestorationChannel { + private static TAG = "RestorationChannel"; + private static CHANNEL_NAME = "flutter/restoration"; + + /** + * Whether the channel delays responding to the framework's initial request for restoration data + * until {@code setRestorationData} has been called. + * + *

If the engine never calls {@code setRestorationData} this flag must be set to false. If set + * to true, the engine must call {@code setRestorationData} either with the actual restoration + * data as argument or null if it turns out that there is no restoration data. + * + *

If the response to the framework's request for restoration data is not delayed until the + * data has been set via {@code setRestorationData}, the framework may intermittently initialize + * itself to default values until the restoration data has been made available. Setting this flag + * to true avoids that extra work. + */ + public waitForRestorationData: boolean; + + // Holds the most current restoration data which may have been provided by the engine + // via "setRestorationData" or by the framework via the method channel. This is the data the + // framework should be restored to in case the app is terminated. + private restorationData: Uint8Array = new Uint8Array(); + private channel: MethodChannel; + private pendingFrameworkRestorationChannelRequest: MethodResult; + private engineHasProvidedData: boolean = false; + private frameworkHasRequestedData: boolean = false; + private handler: MethodCallHandler = new RestorationChannelMethodCallHandler(this.restorationData); + + constructor(channelOrExecutor: MethodChannel | DartExecutor, waitForRestorationData: boolean) { + if (channelOrExecutor instanceof MethodChannel) { + this.channel = channelOrExecutor; + } else { + this.channel = new MethodChannel(channelOrExecutor, RestorationChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); + } + this.waitForRestorationData = waitForRestorationData; + this.channel.setMethodCallHandler(this.handler); + } + + /** Obtain the most current restoration data that the framework has provided. */ + getRestorationData(): Uint8Array { + return this.restorationData; + } + + /** Set the restoration data from which the framework will restore its state. */ + setRestorationData(data: Uint8Array) { + this.engineHasProvidedData = true; + if (this.pendingFrameworkRestorationChannelRequest != null) { + // If their is a pending request from the framework, answer it. + this.pendingFrameworkRestorationChannelRequest.success(RestorationChannelMethodCallHandler.packageData(data)); + this.pendingFrameworkRestorationChannelRequest = null; + this.restorationData = data; + } else if (this.frameworkHasRequestedData) { + // If the framework has previously received the engine's restoration data, push the new data + // directly to it. This case can happen when "waitForRestorationData" is false and the + // framework retrieved the restoration state before it was set via this method. + // Experimentally, this can also be used to restore a previously used engine to another state, + // e.g. when the engine is attached to a new activity. + this.channel.invokeMethod("push", RestorationChannelMethodCallHandler.packageData(data), { + success: (result: ESObject) :void => { + this.restorationData = data; + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) :void => { + Log.e(RestorationChannel.TAG, + "Error " + errorCode + " while sending restoration data to framework: " + errorMessage); + }, + + notImplemented: () :void => { + // do nothing + } + }) + } else { + // Otherwise, just cache the data until the framework asks for it. + this.restorationData = data; + } + } + + /** + * Clears the current restoration data. + * + *

This should be called just prior to a hot restart. Otherwise, after the hot restart the + * state prior to the hot restart will get restored. + */ + clearData() { + this.restorationData = null; + } +} + +class RestorationChannelMethodCallHandler implements MethodCallHandler { + public waitForRestorationData: boolean; + private restorationData: Uint8Array; + private engineHasProvidedData: boolean = false; + private frameworkHasRequestedData: boolean = false; + private channel: MethodChannel; + private pendingFrameworkRestorationChannelRequest: MethodResult; + + constructor(restorationData: Uint8Array) { + this.restorationData = restorationData; + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + const method = call.method; + const args: ESObject = call.args; + switch (method) { + case "put": { + this.restorationData = args; + result.success(null); + break; + } + case "get": { + this.frameworkHasRequestedData = true; + if (this.engineHasProvidedData || !this.waitForRestorationData) { + result.success(RestorationChannelMethodCallHandler.packageData(this.restorationData)); + // Do not delete the restoration data on the engine side after sending it to the + // framework. We may need to hand this data back to the operating system if the + // framework never modifies the data (and thus doesn't send us any + // data back). + } else { + this.pendingFrameworkRestorationChannelRequest = result; + } + break; + } + default: { + result.notImplemented(); + break; + } + } + } + + static packageData(data: Uint8Array): Map { + const packaged: Map = new Map(); + packaged.set("enabled", true); + packaged.set("data", data); + return packaged; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..b40cd5536a335c48b0d9c9defabc02cfdea50f7e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +export enum PlatformBrightness { + LIGHT = "light", + DARK = "dark" +} + +const TAG = "SettingsChannel"; +const TEXT_SCALE_FACTOR = "textScaleFactor"; +const NATIVE_SPELL_CHECK_SERVICE_DEFINED = "nativeSpellCheckServiceDefined"; +const BRIEFLY_SHOW_PASSWORD = "brieflyShowPassword"; +const ALWAYS_USE_24_HOUR_FORMAT = "alwaysUse24HourFormat"; +const PLATFORM_BRIGHTNESS = "platformBrightness"; +export default class SettingsChannel { + private static CHANNEL_NAME = "flutter/settings"; + + private channel: BasicMessageChannel; + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, SettingsChannel.CHANNEL_NAME, JSONMessageCodec.INSTANCE); + } + + startMessage(): MessageBuilder { + return new MessageBuilder(this.channel); + } +} + +class MessageBuilder { + private channel: BasicMessageChannel; + private message: Map = new Map(); + + constructor(channel: BasicMessageChannel) { + this.channel = channel; + } + + setTextScaleFactor(textScaleFactor: Number): MessageBuilder { + this.message.set(TEXT_SCALE_FACTOR, textScaleFactor); + return this; + } + + setNativeSpellCheckServiceDefined(nativeSpellCheckServiceDefined: boolean): MessageBuilder { + this.message.set(NATIVE_SPELL_CHECK_SERVICE_DEFINED, nativeSpellCheckServiceDefined); + return this; + } + + setBrieflyShowPassword(brieflyShowPassword: boolean): MessageBuilder { + this.message.set(BRIEFLY_SHOW_PASSWORD, brieflyShowPassword); + return this; + } + + setAlwaysUse24HourFormat(alwaysUse24HourFormat: boolean): MessageBuilder { + this.message.set(ALWAYS_USE_24_HOUR_FORMAT, alwaysUse24HourFormat); + return this; + } + + setPlatformBrightness(platformBrightness: PlatformBrightness): MessageBuilder { + this.message.set(PLATFORM_BRIGHTNESS, platformBrightness); + return this; + } + + send(): void { + Log.i(TAG, "Sending message: \n" + + "textScaleFactor: " + + this.message.get(TEXT_SCALE_FACTOR) + + "alwaysUse24HourFormat: " + + this.message.get(ALWAYS_USE_24_HOUR_FORMAT) + + "platformBrightness: " + + this.message.get(PLATFORM_BRIGHTNESS)) + this.channel.send(this.message) + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f9ef28154563799368fbbe816ceed3cd78f0d3e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +const TAG: string = "SystemChannel"; + +/** + * fill in javadoc for SystemChannel. + */ +export default class SystemChannel { + public channel: BasicMessageChannel; + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, "flutter/system", JSONMessageCodec.INSTANCE); + } + + public sendMemoryPressureWarning(): void { + Log.i(TAG, "Sending memory pressure warning to Flutter"); + let message : Map = new Map().set("type", "memoryPressure"); + this.channel.send(message); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..d54c448e027d069baaacbe66bf877c50823cb6d5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel, { MessageHandler, Reply } from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import DartExecutor from '../dart/DartExecutor'; +import Log from '../../../util/Log'; + +const TAG = "TestChannel" + +export default class TestChannel { + private channel: BasicMessageChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, "flutter/test", JSONMessageCodec.INSTANCE); + let callback = new MessageCallback(); + this.channel.setMessageHandler(callback); + } +} + +class MessageCallback implements MessageHandler { + onMessage(message: string, reply: Reply) { + Log.d(TAG, "receive msg = " + message); + reply.reply("收到消息啦:" + message); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..afdbecc9829a7520eef0c3409545572be381a96b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import TextInputPlugin from '../../../plugin/editing/TextInputPlugin'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG = "TextInputChannel"; + +export default class TextInputChannel { + private static CHANNEL_NAME = "flutter/textinput"; + public channel: MethodChannel; + textInputMethodHandler: TextInputMethodHandler; + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, TextInputChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + let callback = new TextInputCallback(); + callback.textInputMethodHandler = this.textInputMethodHandler; + this.channel.setMethodCallHandler(callback); + } + + setTextInputMethodHandler(textInputMethodHandler: TextInputMethodHandler): void { + this.textInputMethodHandler = textInputMethodHandler; + } + + requestExistingInputState(): void { + this.channel.invokeMethod("TextInputClient.requestExistingInputState", null); + } + + createEditingStateJSON(text: String, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number): ESObject { + return new Map() + .set("text", text) + .set("selectionBase", selectionStart) + .set("selectionExtent", selectionEnd) + .set("composingBase", composingStart) + .set("composingExtent", composingEnd); + } + + /** + * Instructs Flutter to update its text input editing state to reflect the given configuration. + */ + updateEditingState(inputClientId: number, + text: String, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number): void { + Log.d(TAG, "updateEditingState:" + + "Text: " + text + " Selection start: " + selectionStart + " Selection end: " + + selectionEnd + " Composing start: " + composingStart + " Composing end: " + composingEnd); + const state: ESObject = this.createEditingStateJSON(text, selectionStart, selectionEnd, composingStart, composingEnd); + this.channel.invokeMethod('TextInputClient.updateEditingState', [inputClientId, state]); + Log.d(TAG,"updateEditingState end"); + + } + + newline(inputClientId: number): void { + Log.d(TAG, "Sending 'newline' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.newline"]); + } + + go(inputClientId: number): void { + Log.d(TAG, "Sending 'go' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.go"]); + } + + search(inputClientId: number): void { + Log.d(TAG, "Sending 'search' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.search"]); + } + + send(inputClientId: number): void { + Log.d(TAG, "Sending 'send' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.send"]); + } + + done(inputClientId: number): void { + Log.d(TAG, "Sending 'done' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.done"]); + } + + next(inputClientId: number): void { + Log.d(TAG, "Sending 'next' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.next"]); + } + + previous(inputClientId: number): void { + Log.d(TAG, "Sending 'previous' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.previous"]); + } + + unspecifiedAction(inputClientId: number): void { + Log.d(TAG, "Sending 'unspecifiedAction' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.unspecifiedAction"]); + } + + commitContent(inputClientId: number): void { + Log.d(TAG, "Sending 'commitContent' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.commitContent"]); + } + + performPrivateCommand(inputClientId: number, action: string, data: ESObject) { + + } + + + +} + + +export interface TextInputMethodHandler { + show(): void; + + hide(): void; + + requestAutofill(): void; + + finishAutofillContext(shouldSave: boolean): void; + + setClient(textInputClientId: number, configuration: Configuration): void; + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void; + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void; + + setEditingState(editingState: TextEditState): void; + + clearClient(): void; + +} + +export class Configuration { + obscureText: boolean; + autocorrect: boolean; + enableSuggestions: boolean; + enableIMEPersonalizedLearning: boolean; + enableDeltaModel: boolean; + textCapitalization: TextCapitalization; + inputType:InputType; + inputAction: Number; + actionLabel: String; + contentCommitMimeTypes: String[]; + fields: Configuration[]; + + constructor(obscureText: boolean, + autocorrect: boolean, + enableSuggestions: boolean, + enableIMEPersonalizedLearning: boolean, + enableDeltaModel: boolean, + inputType: InputType, + inputAction: Number, + actionLabel: String, ) { + } + getTextCapitalizationFromValue(encodedName: string): TextCapitalization { + let textKeys = [ + TextCapitalization.CHARACTERS, TextCapitalization.WORDS, + TextCapitalization.SENTENCES, TextCapitalization.NONE + ]; + for (let i = 0; i < textKeys.length; i++) { + let key = textKeys[i]; + if (TextCapitalization[key] === encodedName) { + return key; + } + } + throw new Error("No such TextCapitalization: " + encodedName); + } +} + +enum TextCapitalization { + CHARACTERS = "TextCapitalization.characters", + WORDS = "TextCapitalization.words", + SENTENCES = "TextCapitalization.sentences", + NONE = "TextCapitalization.none", +} + +export enum TextInputType { + TEXT = "TextInputType.text", + DATETIME = "TextInputType.datetime", + NAME = "TextInputType.name", + POSTAL_ADDRESS = "TextInputType.address", + NUMBER = "TextInputType.number", + PHONE = "TextInputType.phone", + MULTILINE = "TextInputType.multiline", + EMAIL_ADDRESS = "TextInputType.emailAddress", + URL = "TextInputType.url", + VISIBLE_PASSWORD = "TextInputType.visiblePassword", + NONE = "TextInputType.none", +} + +export class InputType { + type: TextInputType; + isSigned: boolean; + isDecimal: boolean; + + constructor(type: TextInputType, isSigned: boolean, isDecimal: boolean) { + this.type = type; + this.isSigned = isSigned; + this.isDecimal = isDecimal; + } + + static fromJson(json: ESObject): InputType { + return new InputType(InputType.getTextInputTypeFromValue(json.name as string), + json.signed as boolean, json.decimal as boolean) + } + + static getTextInputTypeFromValue(encodedName: string): TextInputType { + let textKeys = [ + TextInputType.TEXT, TextInputType.DATETIME, TextInputType.NAME, + TextInputType.POSTAL_ADDRESS, TextInputType.NUMBER, TextInputType.PHONE, + TextInputType.MULTILINE, TextInputType.EMAIL_ADDRESS, TextInputType.URL, + TextInputType.VISIBLE_PASSWORD, TextInputType.NONE + ]; + for (let i = 0; i < textKeys.length; i++) { + let key = textKeys[i]; + if (TextInputType[key] == encodedName) { + return key; + } + } + throw new Error("No such TextInputType: " + encodedName); + } +} + +export class TextEditState { + private static TAG = "TextEditState"; + text: string; + selectionStart: number; + selectionEnd: number; + composingStart: number; + composingEnd: number; + + constructor(text: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number) { + if ((selectionStart != -1 || selectionEnd != -1) + && (selectionStart < 0 || selectionEnd < 0)) { + throw new Error("invalid selection: (" + selectionStart + ", " + selectionEnd + ")"); + } + + if ((composingStart != -1 || composingEnd != -1) + && (composingStart < 0 || composingStart > composingEnd)) { + throw new Error("invalid composing range: (" + composingStart + ", " + composingEnd + ")"); + } + + if (composingEnd > text.length) { + throw new Error("invalid composing start: " + composingStart); + } + + if (selectionStart > text.length) { + throw new Error("invalid selection start: " + selectionStart); + } + + if (selectionEnd > text.length) { + throw new Error("invalid selection end: " + selectionEnd); + } + + this.text = text; + this.selectionStart = selectionStart; + this.selectionEnd = selectionEnd; + this.composingStart = composingStart; + this.composingEnd = composingEnd; + } + + hasSelection(): boolean { + // When selectionStart == -1, it's guaranteed that selectionEnd will also + // be -1. + return this.selectionStart >= 0; + } + + hasComposing(): boolean { + return this.composingStart >= 0 && this.composingEnd > this.composingStart; + } + + static fromJson(textEditState: ESObject): TextEditState { + return new TextEditState( + textEditState.text, + textEditState.selectionBase, + textEditState.selectionExtent, + textEditState.composingBase, + textEditState.composingExtent + ) + } +} + +class TextInputCallback implements MethodCallHandler { + textInputMethodHandler: TextInputMethodHandler; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.textInputMethodHandler == null) { + return; + } + let method: string = call.method; + let args: ESObject = call.args; + Log.d(TAG, "Received '" + method + "' message."); + switch (method) { + case "TextInput.show": + this.textInputMethodHandler.show(); + Log.d(TAG, "textInputMethodHandler.show()"); + result.success(null); + break; + case "TextInput.hide": + this.textInputMethodHandler.hide(); + result.success(null); + break; + case "TextInput.setClient": + const textInputClientId: number = args[0] as number; + //TODO: parse configuration + const config: Configuration = null; + this.textInputMethodHandler.setClient(textInputClientId, config); + result.success(null); + break; + case "TextInput.requestAutofill": + //TODO: requestAutofill + result.notImplemented(); + break; + case "TextInput.setPlatformViewClient": + //TODO: + result.notImplemented(); + break; + case "TextInput.setEditingState": + this.textInputMethodHandler.setEditingState(TextEditState.fromJson(args)); + result.success(null); + break; + case "TextInput.setEditableSizeAndTransform": + //TODO: + result.notImplemented(); + break; + case "TextInput.clearClient": + this.textInputMethodHandler.clearClient(); + result.success(null); + break; + case "TextInput.sendAppPrivateCommand": + //TODO: + result.notImplemented(); + break; + case "TextInput.finishAutofillContext": + //TODO: + result.notImplemented(); + break; + default: + result.notImplemented(); + break; + } + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ecfc7d5ef46c57923679789eb82f86eb83ef77 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default interface ExclusiveAppComponent { + /** + * Called when another App Component is about to become attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} this App Component is currently attached to. + * + *

This App Component's connections to the {@link io.flutter.embedding.engine.FlutterEngine} + * are still valid at the moment of this call. + */ + detachFromFlutterEngine(): void; + + /** + * Retrieve the App Component behind this exclusive App Component. + * + * @return The app component. + */ + getAppComponent(): T; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..07a374a7109e9a1ffcd5680220534c9796681e64 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -0,0 +1,414 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import window from '@ohos.window'; +import { FlutterAbilityDelegate, Host } from './FlutterAbilityDelegate'; +import Log from '../../util/Log'; +import FlutterEngine from '../engine/FlutterEngine'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import common from '@ohos.app.ability.common'; +import Want from '@ohos.app.ability.Want'; +import display from '@ohos.display'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import { AsyncCallback } from '@ohos.base'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import I18n from '@ohos.i18n' +import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; +import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; +import { DVModelContainer } from '../../view/DynamicView/dynamicView'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { Configuration } from '@ohos.app.ability.Configuration'; + +const TAG = "FlutterAbility"; +/** + * flutter ohos基础ability,请在让主ability继承自该类。 + * 该类主要职责: + * 1、持有FlutterAbilityDelegate并初始化; + * 2、生命周期传递; + */ +export class FlutterAbility extends UIAbility implements Host { + private delegate: FlutterAbilityDelegate; + private windowStage: window.WindowStage; + private mainWindow: window.Window; + private viewportMetrics = new ViewportMetrics(); + private displayInfo: display.Display; + + /** + * onCreate + * 1、create and attach delegate + * 2、config windows transparent noNeed? + * 3、lifecycle.onCreate + * 4. setContentView() noNeed + */ + async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + Log.i(TAG, "bundleCodeDir=" + this.context.bundleCodeDir); + // globalThis.flutterAbility = this + this.displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = this.displayInfo.densityPixels + + this.delegate = new FlutterAbilityDelegate(this); + await this.delegate.onAttach(this.context); + Log.i(TAG, 'onAttach end'); + this.delegate.platformPlugin.setUIAbilityContext(this.context); + this.delegate.onRestoreInstanceState(want); + this.delegate.sendSettings(); + + if (this.stillAttachedForEvent("onCreate")) { + this.delegate.onCreate(); + } + + console.log('MyAbility onCreate'); + // globalThis.applicationContext = this.context.getApplicationContext(); + } + + onDestroy() { + if (this.stillAttachedForEvent("onDestroy")) { + this.delegate.onDestroy(); + } + } + + /** + * window状态改变回调 + * @param windowStage + */ + async onWindowStageCreate(windowStage: window.WindowStage) { + this.windowStage = windowStage + try { + windowStage.on('windowStageEvent', (data) => { + let stageEventType: window.WindowStageEventType = data; + switch (stageEventType) { + case window.WindowStageEventType.SHOWN: // 切到前台 + Log.i(TAG, 'windowStage foreground.'); + break; + case window.WindowStageEventType.ACTIVE: // 获焦状态 + Log.i(TAG, 'windowStage active.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(true); + } + break; + case window.WindowStageEventType.INACTIVE: // 失焦状态 + Log.i(TAG, 'windowStage inactive.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(false); + } + break; + case window.WindowStageEventType.HIDDEN: // 切到后台 + Log.i(TAG, 'windowStage background.'); + break; + default: + break; + } + }); + + this.mainWindow = windowStage.getMainWindowSync() + this.mainWindow.on('windowSizeChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('avoidAreaChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('keyboardHeightChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.loadContent(); + this.mainWindow.setWindowLayoutFullScreen(true); + } catch (exception) { + Log.e(TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception)); + } + } + + loadContent() { + if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { + Log.i(TAG, 'loadContent'); + this.windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Log.e(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + this.onWindowPropertiesUpdated(); + Log.i(TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + if (this.stillAttachedForEvent("onWindowStageCreate")) { + this.delegate.onWindowStageCreate(); + } + this.delegate.getFlutterNapi().updateRefreshRate(this.displayInfo.refreshRate) + this.onFlutterEngineReady() + } + } + + onFlutterEngineReady(): void { + + } + + private updateViewportMetrics() { + this.delegate.getFlutterNapi().setViewportMetrics(this.viewportMetrics.devicePixelRatio, + this.viewportMetrics.physicalWidth, + this.viewportMetrics.physicalHeight, + this.viewportMetrics.physicalViewPaddingTop, + this.viewportMetrics.physicalViewPaddingRight, + this.viewportMetrics.physicalViewPaddingBottom, + this.viewportMetrics.physicalViewPaddingLeft, + this.viewportMetrics.physicalViewInsetTop, + this.viewportMetrics.physicalViewInsetRight, + this.viewportMetrics.physicalViewInsetBottom, + this.viewportMetrics.physicalViewInsetLeft, + this.viewportMetrics.systemGestureInsetTop, + this.viewportMetrics.systemGestureInsetRight, + this.viewportMetrics.systemGestureInsetBottom, + this.viewportMetrics.systemGestureInsetLeft, + this.viewportMetrics.physicalTouchSlop, + new Array(0), + new Array(0), + new Array(0)) + } + + onWindowStageDestroy() { + if (this.stillAttachedForEvent("onWindowStageDestroy")) { + this.delegate.onWindowStageDestroy(); + } + } + + onForeground() { + if (this.stillAttachedForEvent("onForeground")) { + this.delegate.onForeground(); + } + } + + onBackground() { + if (this.stillAttachedForEvent("onBackground")) { + this.delegate.onBackground(); + } + } + + release() { + if (this.delegate != null) { + this.delegate.release(); + this.delegate = null; + } + } + + /** + * host所有实现方法开始======start + */ + + getAbility(): UIAbility { + return this; + } + + shouldDispatchAppLifecycleState(): boolean { + return true; + } + + provideFlutterEngine(context: common.Context): FlutterEngine { + return null; + } + + configureFlutterEngine(flutterEngine: FlutterEngine) { + + } + + cleanUpFlutterEngine(flutterEngine: FlutterEngine) { + + } + + getFlutterShellArgs(): FlutterShellArgs { + return FlutterShellArgs.fromWant(this.getWant()); + } + + getDartEntrypointArgs(): Array { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; + } + return new Array() + } + + detachFromFlutterEngine() { + if (this.delegate != null) { + this.delegate.onDetach(); + } + } + + popSystemNavigator(): boolean { + return false; + } + + shouldAttachEngineToActivity(): boolean { + return true; + } + + getDartEntrypointLibraryUri(): string { + return null; + } + + getAppBundlePath(): string { + return null; + } + + getDartEntrypointFunctionName(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; + } + return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT + } + + getInitialRoute(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string; + } + return null + } + + getWant(): Want { + return this.launchWant; + } + + shouldDestroyEngineWithHost(): boolean { + return true; + } + + shouldRestoreAndSaveState(): boolean{ + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; + } + if (this.getCachedEngineId() != null) { + // Prevent overwriting the existing state in a cached engine with restoration state. + return false; + } + return true; + } + + getCachedEngineId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string + } + + getCachedEngineGroupId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string + } + + /** + * host所有实现方法结束======end + */ + private stillAttachedForEvent(event: string) { + Log.i(TAG, 'Ability ' + event); + if (this.delegate == null) { + Log.w(TAG, "FlutterAbility " + event + " call after release."); + return false; + } + if (!this.delegate.isAttached) { + Log.w(TAG, "FlutterAbility " + event + " call after detach."); + return false; + } + return true; + } + + addPlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.addPlugin(plugin) + } + } + + removePlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.removePlugin(plugin) + } + } + + private onWindowPropertiesUpdated(){ + if (!this.delegate.isAttached) { + return; + } + let systemAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let gestureAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + let keyboardAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + const properties = this.mainWindow.getWindowProperties(); + this.viewportMetrics.physicalWidth = properties.windowRect.width; + this.viewportMetrics.physicalHeight = properties.windowRect.height; + + this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea.topRect.height + this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea.leftRect.width + this.viewportMetrics.physicalViewPaddingBottom = systemAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea.rightRect.width + + this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea.topRect.height + this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea.leftRect.width + this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea.rightRect.width + + this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea.topRect.height + this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea.leftRect.width + this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea.bottomRect.height + this.viewportMetrics.systemGestureInsetRight = gestureAvoidArea.rightRect.width + + this.updateViewportMetrics() + } + + onMemoryLevel(level: AbilityConstant.MemoryLevel): void { + Log.i(TAG, 'onMemoryLevel: ' + level); + if (level === AbilityConstant.MemoryLevel.MEMORY_LEVEL_CRITICAL) { + this.delegate.onLowMemory(); + } + } + + onConfigurationUpdated(config: Configuration){ + Log.i(TAG, 'onConfigurationUpdated config:' + JSON.stringify(config)); + this.delegate.flutterEngine.getSettingsChannel().startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK + ? PlatformBrightness.LIGHT : PlatformBrightness.DARK); + } + + getWindowId(callback: AsyncCallback): void { + if (callback === null) { + return; + } + try { + window.getLastWindow(this.context, (error, win) => { + if (error.code) { + callback(error, -1); + return; + } + let windowId = win.getWindowProperties().id; + callback(error, windowId); + }); + } catch (err) { + Log.e(TAG, "get window id error!"); + callback(err, -1); + } + } +} + +export class ViewportMetrics { + devicePixelRatio: number = 1.0; + physicalWidth: number = 0; + physicalHeight: number = 0; + physicalViewPaddingTop: number = 0; + physicalViewPaddingRight: number = 0; + physicalViewPaddingBottom: number = 0; + physicalViewPaddingLeft: number = 0; + physicalViewInsetTop: number = 0; + physicalViewInsetRight: number = 0; + physicalViewInsetBottom: number = 0; + physicalViewInsetLeft: number = 0; + systemGestureInsetTop: number = 0; + systemGestureInsetRight: number = 0; + systemGestureInsetBottom: number = 0; + systemGestureInsetLeft: number = 0; + physicalTouchSlop = -1; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9046981a47219a7eb553dd4d3baeefa639069281 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import FlutterEngineConfigurator from './FlutterEngineConfigurator'; +import FlutterEngineProvider from './FlutterEngineProvider'; +import FlutterEngine from '../engine/FlutterEngine'; +import PlatformPlugin, { PlatformPluginDelegate } from '../../plugin/PlatformPlugin'; +import Want from '@ohos.app.ability.Want'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import DartExecutor, { DartEntrypoint } from '../engine/dart/DartExecutor'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import Log from '../../util/Log'; +import FlutterInjector from '../../FlutterInjector'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from './ExclusiveAppComponent'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import FlutterEngineCache from '../engine/FlutterEngineCache'; +import FlutterEngineGroupCache from '../engine/FlutterEngineGroupCache'; +import FlutterEngineGroup, { Options } from '../engine/FlutterEngineGroup'; +import MouseCursorPlugin, { MouseCursorViewDelegate } from '../../plugin/mouse/MouseCursorPlugin'; +import Settings from './Settings'; + +const TAG = "FlutterAbilityDelegate"; +const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; +const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; + +/** + * 主要职责: + * 1、初始化engine + * 2、处理ability生命周期回调 + */ +class FlutterAbilityDelegate implements ExclusiveAppComponent { + private host: Host; + flutterEngine: FlutterEngine; + platformPlugin: PlatformPlugin; + private context: common.Context; + private textInputPlugin: TextInputPlugin; + private isFlutterEngineFromHost: boolean; + private engineGroup: FlutterEngineGroup; + private mouseCursorPlugin: MouseCursorPlugin; + private settings: Settings; + + constructor(host: Host) { + this.host = host; + } + + /** + * 是否还attach在ability上 + */ + isAttached = false; + + async onAttach(context: common.Context): Promise { + this.context = context; + this.ensureAlive(); + if (this.flutterEngine == null) { + await this.setupFlutterEngine(); + } + //shouldAttachEngineToActivity + if (this.host.shouldAttachEngineToActivity()) { + // Notify any plugins that are currently attached to our FlutterEngine that they + // are now attached to an Ability. + Log.d(TAG, "Attaching FlutterEngine to the Ability that owns this delegate."); + this.flutterEngine.getAbilityControlSurface().attachToAbility(this); + } + + //providePlatformPlugin + + //configureFlutterEngine + this.isAttached = true; + Log.d(TAG, "onAttach end start loadcontent") + this.host.loadContent() + this.textInputPlugin = new TextInputPlugin(this.flutterEngine.getTextInputChannel()); + this.platformPlugin = new PlatformPlugin(this.flutterEngine.getPlatformChannel(), this.context); + this.mouseCursorPlugin = new MouseCursorPlugin(this.host, this.flutterEngine.getMouseCursorChannel()); + this.settings = new Settings(this.flutterEngine.getSettingsChannel()); + this.flutterEngine.getSystemLanguages(); + } + + /** + * 加载app.so资源或者snapshot + */ + private doInitialFlutterViewRun(): void { + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + const libraryUri = this.host.getDartEntrypointLibraryUri(); + Log.d(TAG, "Executing Dart entrypoint: " + this.host.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); + + // The engine needs to receive the Flutter app's initial route before executing any + // Dart code to ensure that the initial route arrives in time to be applied. + this.flutterEngine.getNavigationChannel().setInitialRoute(initialRoute); + + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride == '') { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint: DartEntrypoint = new DartEntrypoint( + appBundlePathOverride, + this.host.getDartEntrypointLibraryUri(), + this.host.getDartEntrypointFunctionName() + ); + this.flutterEngine.dartExecutor.executeDartEntrypoint(dartEntrypoint, this.host.getDartEntrypointArgs()); + } + + private maybeGetInitialRouteFromIntent(want: Want): string { + return null; + } + + + /** + * 通过参数,配置flutterEngine + * @param want + */ + onRestoreInstanceState(want: Want) { + let frameworkState: Uint8Array = want.parameters[FRAMEWORK_RESTORATION_BUNDLE_KEY] as Uint8Array; + if (this.host.shouldRestoreAndSaveState()) { + this.flutterEngine.getRestorationChannel().setRestorationData(frameworkState ?? null); + } + } + + /** + * 初始化flutterEngine + */ + async setupFlutterEngine() { + // First, check if the host wants to use a cached FlutterEngine. + const cachedEngineId = this.host.getCachedEngineId(); + Log.d(TAG, "cachedEngineId=" + cachedEngineId); + if (cachedEngineId && cachedEngineId.length > 0) { + this.flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); + this.isFlutterEngineFromHost = true; + if (this.flutterEngine == null) { + throw new Error( + "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" + + cachedEngineId + + "'"); + } + return; + } + + // Second, defer to subclasses for a custom FlutterEngine. + this.flutterEngine = this.host.provideFlutterEngine(this.context); + if (this.flutterEngine != null) { + this.isFlutterEngineFromHost = true; + return; + } + + // Third, check if the host wants to use a cached FlutterEngineGroup + // and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine + const cachedEngineGroupId = this.host.getCachedEngineGroupId(); + Log.d(TAG, "cachedEngineGroupId=" + cachedEngineGroupId); + if (cachedEngineGroupId != null) { + const flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); + if (flutterEngineGroup == null) { + throw new Error( + "The requested cached FlutterEngineGroup did not exist in the FlutterEngineGroupCache: '" + + cachedEngineGroupId + + "'"); + } + + this.flutterEngine = await flutterEngineGroup.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context))); + this.isFlutterEngineFromHost = false; + return; + } + + // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our + // FlutterView. + Log.d( + TAG, + "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); + + let group = this.engineGroup; + if (group == null) { + group = new FlutterEngineGroup(); + await group.checkLoader(this.context, this.host.getFlutterShellArgs().toArray()); + } + this.flutterEngine = await group.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context) + .setAutomaticallyRegisterPlugins(false).setWaitForRestorationData(this.host.shouldRestoreAndSaveState()))); + this.isFlutterEngineFromHost = false; + } + + addEntrypointOptions(options: Options): Options { + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride.length == 0) { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint = new DartEntrypoint(appBundlePathOverride, null, this.host.getDartEntrypointFunctionName()); + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + return options + .setDartEntrypoint(dartEntrypoint) + .setInitialRoute(initialRoute) + .setDartEntrypointArgs(this.host.getDartEntrypointArgs()); + } + + /** + * 释放所有持有对象 + */ + release() { + this.host = null; + this.flutterEngine = null; + } + + onDetach() { + if (this.host.shouldAttachEngineToActivity()) { + // Notify plugins that they are no longer attached to an Activity. + Log.d(TAG, "Detaching FlutterEngine from the Ability"); + this.flutterEngine.getAbilityControlSurface().detachFromAbility(); + } + } + + onLowMemory(): void { + this.getFlutterNapi().notifyLowMemoryWarning(); + this.flutterEngine.getSystemChannel().sendMemoryPressureWarning(); + } + + /** + * 生命周期回调 + */ + + onCreate() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsInactive(); + } + } + + onDestroy() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsDetached(); + } + this.textInputPlugin.detach(); + } + + onWindowStageCreate() { + this.ensureAlive(); + this.doInitialFlutterViewRun(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onWindowStageDestroy() { + + } + + onWindowFocusChanged(hasFocus: boolean):void { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getAbilityControlSurface().onWindowFocusChanged(hasFocus); + if (hasFocus) { + this.flutterEngine.getLifecycleChannel().aWindowIsFocused(); + } else { + this.flutterEngine.getLifecycleChannel().noWindowsAreFocused(); + } + } + } + + onForeground() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onBackground() { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsPaused(); + } + } + + /** + * 生命周期回调结束 + */ + + shouldDispatchAppLifecycleState(): boolean { + return this.host.shouldDispatchAppLifecycleState() && this.isAttached; + } + + ensureAlive() { + if (this.host == null) { + throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); + } + } + + getFlutterNapi() { + return this.flutterEngine.getFlutterNapi() + } + + detachFromFlutterEngine() { + if (this.host.shouldDestroyEngineWithHost()) { + // The host owns the engine and should never have its engine taken by another exclusive + // activity. + throw new Error( + "The internal FlutterEngine created by " + + this.host + + " has been attached to by another activity. To persist a FlutterEngine beyond the " + + "ownership of this ablity, explicitly create a FlutterEngine"); + } + + // Default, but customizable, behavior is for the host to call {@link #onDetach} + // deterministically as to not mix more events during the lifecycle of the next exclusive + // activity. + this.host.detachFromFlutterEngine(); + } + + getAppComponent(): UIAbility { + const ability = this.host.getAbility(); + if (ability == null) { + throw new Error( + "FlutterActivityAndFragmentDelegate's getAppComponent should only " + + "be queried after onAttach, when the host's ability should always be non-null"); + } + return ability; + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.ensureAlive() + if (this.flutterEngine != null) { + Log.i(TAG, "Forwarding onNewWant() to FlutterEngine and sending pushRouteInformation message."); + this.flutterEngine.getAbilityControlSurface().onNewWant(want, launchParams); + const initialRoute = this.maybeGetInitialRouteFromIntent(want); + if (initialRoute && initialRoute.length > 0) { + this.flutterEngine.getNavigationChannel().pushRouteInformation(initialRoute); + } + } else { + Log.w(TAG, "onNewIntent() invoked before FlutterFragment was attached to an Activity."); + } + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); + this.ensureAlive(); + if (this.host.shouldRestoreAndSaveState()) { + wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] = this.flutterEngine.getRestorationChannel().getRestorationData(); + } + if (this.host.shouldAttachEngineToActivity()) { + const plugins:Record = {} + const result = this.flutterEngine.getAbilityControlSurface().onSaveState(reason, plugins); + wantParam[PLUGINS_RESTORATION_BUNDLE_KEY] = plugins; + return result + } + return AbilityConstant.OnSaveResult.ALL_REJECT + } + + addPlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().add(plugin) + } + + removePlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().remove(plugin.getUniqueClassName()) + } + + sendSettings(): void { + this.settings.sendSettings() + } +} + + +/** + * FlutterAbility句柄 + */ +interface Host extends FlutterEngineProvider, FlutterEngineConfigurator, PlatformPluginDelegate, MouseCursorViewDelegate { + + getAbility(): UIAbility; + + loadContent():void; + + shouldDispatchAppLifecycleState(): boolean; + + detachFromFlutterEngine(); + + shouldAttachEngineToActivity(): boolean; + + getCachedEngineId(): string; + + getCachedEngineGroupId(): string; + + /** + * Returns true if the {@link io.flutter.embedding.engine.FlutterEngine} used in this delegate + * should be destroyed when the host/delegate are destroyed. + */ + shouldDestroyEngineWithHost(): boolean; + + /** Returns the {@link FlutterShellArgs} that should be used when initializing Flutter. */ + getFlutterShellArgs(): FlutterShellArgs; + + /** Returns arguments that passed as a list of string to Dart's entrypoint function. */ + getDartEntrypointArgs(): Array; + + /** + * Returns the URI of the Dart library which contains the entrypoint method (example + * "package:foo_package/main.dart"). If null, this will default to the same library as the + * `main()` function in the Dart program. + */ + getDartEntrypointLibraryUri(): string; + + /** Returns the path to the app bundle where the Dart code exists. */ + getAppBundlePath(): string; + + /** + * Returns the Dart entrypoint that should run when a new {@link + * io.flutter.embedding.engine.FlutterEngine} is created. + */ + getDartEntrypointFunctionName(): string; + + /** Returns the initial route that Flutter renders. */ + getInitialRoute(): string; + + getWant(): Want; + + shouldRestoreAndSaveState(): boolean; +} + +export { Host, FlutterAbilityDelegate } \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets new file mode 100644 index 0000000000000000000000000000000000000000..996f455b9d045411425025f5c68089aee3f8938c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** The mode of the background of a Flutter {@code Activity}, either opaque or transparent. */ +enum BackgroundMode { + /** Indicates a FlutterActivity with an opaque background. This is the default. */ + opaque, + /** Indicates a FlutterActivity with a transparent background. */ + transparent +} + +export default class FlutterAbilityLaunchConfigs { + + static DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint"; + static DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri"; + static INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute"; + static SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; + static NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; + static HANDLE_DEEPLINKING_META_DATA_KEY = "flutter_deeplinking_enabled"; + // Intent extra arguments. + static EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; + static EXTRA_INITIAL_ROUTE = "route"; + static EXTRA_BACKGROUND_MODE = "background_mode"; + static EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; + static EXTRA_DART_ENTRYPOINT_ARGS = "dart_entrypoint_args"; + static EXTRA_CACHED_ENGINE_GROUP_ID = "cached_engine_group_id"; + static EXTRA_DESTROY_ENGINE_WITH_ACTIVITY = "destroy_engine_with_activity"; + static EXTRA_ENABLE_STATE_RESTORATION = "enable_state_restoration"; + + // Default configuration. + static DEFAULT_DART_ENTRYPOINT = "main"; + static DEFAULT_INITIAL_ROUTE = "/"; + static DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets new file mode 100644 index 0000000000000000000000000000000000000000..7953cad0836a9be4bf6bfd940594fdc787f45d66 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; + +export default interface FlutterEngineConfigurator { + + configureFlutterEngine(flutterEngine: FlutterEngine); + + cleanUpFlutterEngine(flutterEngine: FlutterEngine); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bdd7b6a809a77510f8942e81e0d91e7b4970893 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; +import common from '@ohos.app.ability.common'; + +export default interface FlutterEngineProvider { + provideFlutterEngine(context: common.Context): FlutterEngine; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..05695111937b486f3f498e9c87c12bdb85d829c5 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { PlatformViewWrapper } from '../../plugin/platform/PlatformViewWrapper'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { DVModel, + DVModelChildren, + DVModelContainer, + DVModelEvents, + DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +/** + * 基础page组件,承载XComponent组件 + */ +@Component +export struct FlutterPage { + @State message: string = 'Hello World'; + + @State rootDvModel: DVModelContainer = RootDvModeManager.getRootDvMode(); + + build() { + DynamicView({ + model: this.rootDvModel.model as DVModel, + params: this.rootDvModel.model.params as DVModelParameters, + events: this.rootDvModel.model.events as DVModelEvents, + children: this.rootDvModel.model.children as DVModelChildren, + customBuilder: this.rootDvModel.model.builder as ($$: Record<"params",DVModelParameters >) => void + //customBuilder: this.rootDvModel.model.builder as ($$: { params: DVModelParameters }) => void + }) + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets new file mode 100644 index 0000000000000000000000000000000000000000..53f0f0a6c8f5e2ec858ad802a4e4653ed164c31e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; + +export default class OhosTouchProcessor { + private static POINTER_DATA_FIELD_COUNT: number = 35; + + static BYTES_PER_FIELD: number = 8; + + private static POINTER_DATA_FLAG_BATCHED: number = 1; + + public onTouchEvent(event: TouchEvent, transformMatrix: ESObject): void { + + } +} + +export enum PointerChange { + CANCEL = 0, + ADD = 1, + REMOVE = 2, + HOVER = 3, + DOWN = 4, + MOVE = 5, + UP = 6, + PAN_ZOOM_START = 7, + PAN_ZOOM_UPDATE = 8, + PAN_ZOOM_END = 9 +} + +export enum PointerDeviceKind { + TOUCH = 0, + MOUSE = 1, + STYLUS = 2, + INVERTED_STYLUS = 3, + TRACKPAD = 4, + UNKNOWN = 5 +} + +export enum PointerSignalKind { + NONE = 0, + SCROLL = 1, + SCROLL_INERTIA_CANCEL = 2, + SCALE = 3, + UNKNOWN = 4 +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets new file mode 100644 index 0000000000000000000000000000000000000000..a435d2a45cc960a5d6a4eb49c3d131c83b4d2dcb --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import SettingsChannel, { PlatformBrightness } from '../engine/systemchannels/SettingsChannel' +import I18n from '@ohos.i18n' + +export default class Settings { + settingsChannel: SettingsChannel; + + constructor(settingsChannel: SettingsChannel) { + this.settingsChannel = settingsChannel; + } + + sendSettings(): void { + this.settingsChannel.startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setTextScaleFactor(1.0) + .setNativeSpellCheckServiceDefined(false) + .setBrieflyShowPassword(false) + .setPlatformBrightness(PlatformBrightness.LIGHT) + .send(); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets new file mode 100644 index 0000000000000000000000000000000000000000..15814be043c938ddca9560390fad99d6b15a23c3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** Tracks the motion events received by the FlutterView. */ +import PlainArray from '@ohos.util.PlainArray'; +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; +import Queue from '@ohos.util.Queue'; + +export class TouchEventTracker { + private eventById : PlainArray; + private unusedEvents : Queue; + private static INSTANCE:TouchEventTracker; + + public static getInstance(): TouchEventTracker { + if (TouchEventTracker.INSTANCE == null) { + TouchEventTracker.INSTANCE = new TouchEventTracker(); + } + return TouchEventTracker.INSTANCE; + } + + constructor() { + this.eventById = new PlainArray(); + this.unusedEvents = new Queue(); + } + + /** Tracks the event and returns a unique MotionEventId identifying the event. */ + public track(event :TouchEvent) : TouchEventId { + const eventId:TouchEventId = TouchEventId.createUnique(); + this.eventById.add(eventId.getId(), event); + this.unusedEvents.add(eventId.getId()); + return eventId; + } + + /** + * Returns the MotionEvent corresponding to the eventId while discarding all the motion events + * that occurred prior to the event represented by the eventId. Returns null if this event was + * popped or discarded. + */ + public pop(eventId : TouchEventId) : TouchEvent { + // remove all the older events. + while (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() < eventId.getId()) { + this.eventById.remove(this.unusedEvents.pop()); + } + + // remove the current event from the heap if it exists. + if (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() == eventId.getId()) { + this.unusedEvents.pop(); + } + + const event : TouchEvent = this.eventById.get(eventId.getId()); + this.eventById.remove(eventId.getId()); + return event; + } +} + +/** Represents a unique identifier corresponding to a motion event. */ +export class TouchEventId { + private static ID_COUNTER : number = 0; + private id : number; + + constructor(id : number) { + this.id = id; + } + + public static from(id : number) : TouchEventId { + return new TouchEventId(id); + } + + public static createUnique() : TouchEventId { + return new TouchEventId(TouchEventId.ID_COUNTER++); + } + + public getId() : number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae2c6cfd5202c3f2c912720217df452a727f35b6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class WindowInfoRepositoryCallbackAdapterWrapper { + + constructor() { + } + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..9910f14b6d71e2fc70e55eb8c7846ccbeffa0180 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import PlatformChannel, { + AppSwitcherDescription, + Brightness, + ClipboardContentFormat, + HapticFeedbackType, + PlatformMessageHandler, + SoundType, + SystemChromeStyle, + SystemUiMode, + SystemUiOverlay +} from '../embedding/engine/systemchannels/PlatformChannel'; +import pasteboard from '@ohos.pasteboard'; +import Log from '../util/Log'; +import vibrator from '@ohos.vibrator'; +import window from '@ohos.window'; +import common from '@ohos.app.ability.common'; + +/** + * ohos实现platform plugin + */ +export default class PlatformPlugin { + private static TAG = "PlatformPlugin"; + private callback = new PlatformPluginCallback(); + + constructor(platformChannel: PlatformChannel, context: common.Context, platformPluginDelegate?: PlatformPluginDelegate) { + this.callback.platformChannel = platformChannel; + this.callback.context = context; + this.callback.applicationContext = context.getApplicationContext(); + this.callback.platform = this; + + try { + window.getLastWindow(context, (err, data) => { + if (err.code) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + return; + } + this.callback.windowClass = data; + }); + } catch (err) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + } + this.callback.platformPluginDelegate = platformPluginDelegate; + this.callback.platformChannel.setPlatformMessageHandler(this.callback); + } + + + updateSystemUiOverlays(): void { + this.callback.windowClass.setWindowSystemBarEnable(this.callback.showBarOrNavigation); + if (this.callback.currentTheme != null) { + this.callback.setSystemChromeSystemUIOverlayStyle(this.callback.currentTheme); + } + } + + setUIAbilityContext(context: common.UIAbilityContext): void { + this.callback.uiAbilityContext = context; + } + + setSystemChromeChangeListener(): void { + if (this.callback.callbackId == null && this.callback.applicationContext != null) { + let that = this; + this.callback.callbackId = this.callback.applicationContext.on('environment', { + onConfigurationUpdated(config) { + Log.d(PlatformPlugin.TAG, "onConfigurationUpdated: " + that.callback.showBarOrNavigation); + that.callback.platformChannel.systemChromeChanged(that.callback.showBarOrNavigation.includes('status')); + }, + onMemoryLevel(level) { + } + }) + } + } +} + +export interface PlatformPluginDelegate { + popSystemNavigator(): boolean; +} + +class PlatformPluginCallback implements PlatformMessageHandler { + private static TAG = "PlatformPluginCallback"; + platform: PlatformPlugin; + windowClass: window.Window = null; + platformChannel: PlatformChannel; + platformPluginDelegate: PlatformPluginDelegate; + context: common.Context; + showBarOrNavigation: ('status' | 'navigation')[] = ['status', 'navigation']; + uiAbilityContext: common.UIAbilityContext = null; + callbackId: number = null; + applicationContext: common.ApplicationContext = null; + currentTheme: SystemChromeStyle = null; + + playSystemSound(soundType: SoundType) { + } + + vibrateHapticFeedback(feedbackType: HapticFeedbackType) { + switch (feedbackType) { + case HapticFeedbackType.STANDARD: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'touch' }); + break; + case HapticFeedbackType.LIGHT_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'notification' }).then(); + break; + case HapticFeedbackType.MEDIUM_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'ring' }); + break; + case HapticFeedbackType.HEAVY_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'alarm' }); + break; + case HapticFeedbackType.SELECTION_CLICK: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'physicalFeedback' }); + break; + } + } + + setPreferredOrientations(ohosOrientation: number) { + Log.d(PlatformPluginCallback.TAG, "ohosOrientation: " + ohosOrientation); + this.windowClass.setPreferredOrientation(ohosOrientation); + } + + setApplicationSwitcherDescription(description: AppSwitcherDescription) { + // representation described in the given {@code description}. + } + + showSystemOverlays(overlays: SystemUiOverlay[]) { + this.setSystemChromeEnabledSystemUIOverlays(overlays); + } + + showSystemUiMode(mode: SystemUiMode) { + this.setSystemChromeEnabledSystemUIMode(mode); + } + + setSystemUiChangeListener() { + this.platform.setSystemChromeChangeListener(); + } + + restoreSystemUiOverlays() { + this.platform.updateSystemUiOverlays(); + } + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle) { + Log.d(PlatformPluginCallback.TAG, "systemUiOverlayStyle:" + JSON.stringify(systemUiOverlayStyle)); + this.setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle); + } + + popSystemNavigator() { + if (this.platformPluginDelegate != null && this.platformPluginDelegate.popSystemNavigator()) { + return; + } + if (this.uiAbilityContext != null) { + this.uiAbilityContext.terminateSelf(); + } + } + + getClipboardData(format: ClipboardContentFormat): string { + // todo + return ""; + } + + setClipboardData(text: string) { + let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + let clipboard = pasteboard.getSystemPasteboard(); + clipboard.setData(pasteData); + } + + clipboardHasStrings(): boolean { + return false; + } + + setSystemChromeEnabledSystemUIMode(mode: SystemUiMode): void { + Log.d(PlatformPluginCallback.TAG, "mode: " + mode); + let uiConfig: ('status' | 'navigation')[] = []; + if (mode == SystemUiMode.LEAN_BACK) { + //全屏显示,通过点击显示器上的任何位置都可以显示状态和导航栏 + this.windowClass.setWindowLayoutFullScreen(false); + + } else if (mode == SystemUiMode.IMMERSIVE) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,应用程序不会接收到此手势 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.IMMERSIVE_STICKY) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,此手势由应用程序接收 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.EDGE_TO_EDGE) { + //全屏显示,在应用程序上呈现状态和导航元素 + this.windowClass.setWindowLayoutFullScreen(false); + uiConfig = ['status', 'navigation']; + + } else { + return; + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } + + setSystemChromeSystemUIOverlayStyle(systemChromeStyle: SystemChromeStyle): void { + let isStatusBarLightIconValue: boolean = false; + let statusBarColorValue: string = null; + let statusBarContentColorValue: string = null; + let navigationBarColorValue: string = null; + let isNavigationBarLightIconValue: boolean = false; + let navigationBarContentColorValue: string = null; + if (systemChromeStyle.statusBarIconBrightness != null) { + switch (systemChromeStyle.statusBarIconBrightness) { + case Brightness.DARK: + isStatusBarLightIconValue = false; + break; + case Brightness.LIGHT: + isStatusBarLightIconValue = true; + break; + } + } + + if (systemChromeStyle.statusBarColor != null) { + statusBarColorValue = "#" + systemChromeStyle.statusBarColor.toString(16); + } + + if (systemChromeStyle.systemStatusBarContrastEnforced != null) { + + } + + if (systemChromeStyle.systemNavigationBarIconBrightness != null) { + switch (systemChromeStyle.systemNavigationBarIconBrightness) { + case Brightness.DARK: + isNavigationBarLightIconValue = true; + break; + case Brightness.LIGHT: + isNavigationBarLightIconValue = false; + } + } + + if (systemChromeStyle.systemNavigationBarColor != null) { + navigationBarColorValue = "#" + systemChromeStyle.systemNavigationBarColor.toString(16); + } + + if (systemChromeStyle.systemNavigationBarContrastEnforced != null) { + + } + this.currentTheme = systemChromeStyle; + let systemBarProperties = new SystemBarProperties(); + systemBarProperties.statusBarColor = statusBarColorValue; + systemBarProperties.isStatusBarLightIcon = isStatusBarLightIconValue; + systemBarProperties.statusBarContentColor = statusBarContentColorValue; + systemBarProperties.navigationBarColor = navigationBarColorValue; + systemBarProperties.isNavigationBarLightIcon = isNavigationBarLightIconValue; + systemBarProperties.navigationBarContentColor = navigationBarContentColorValue; + Log.d(PlatformPluginCallback.TAG, "systemBarProperties: " + JSON.stringify(systemBarProperties)); + this.windowClass.setWindowSystemBarProperties(systemBarProperties); + } + + setSystemChromeEnabledSystemUIOverlays(overlays: SystemUiOverlay[]): void { + let uiConfig: ('status' | 'navigation')[] = []; + if (overlays.length == 0) { + + } + for (let index = 0; index < overlays.length; ++index) { + let overlayToShow = overlays[index]; + switch (overlayToShow) { + case SystemUiOverlay.TOP_OVERLAYS: + uiConfig.push('status'); //hide navigation + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + uiConfig.push('navigation'); //hide bar + break; + } + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } +} + +class SystemBarProperties { + statusBarColor?: string; + + isStatusBarLightIcon?: boolean; + + statusBarContentColor?: string; + + navigationBarColor?: string; + + isNavigationBarLightIcon?: boolean; + + navigationBarContentColor?: string; +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6e6f6bcfb5b863a2b5c65b9f398ec5e048f4ad6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler } from './BinaryMessenger'; +import Log from '../../util/Log'; +import { BinaryReply } from './BinaryMessenger'; +import { TaskQueue } from './BinaryMessenger'; +import MessageCodec from './MessageCodec'; +import { BinaryMessenger } from './BinaryMessenger'; +/** + * A named channel for communicating with the Flutter application using basic, asynchronous message + * passing. + * + *

Messages are encoded into binary before being sent, and binary messages received are decoded + * into Java objects. The {@link MessageCodec} used must be compatible with the one used by the + * Flutter application. This can be achieved by creating a BasicMessageChannel + * counterpart of this channel on the Dart side. The static Java type of messages sent and received + * is {@code Object}, but only values supported by the specified {@link MessageCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +export default class BasicMessageChannel { + public static TAG = "BasicMessageChannel#"; + public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; + private messenger: BinaryMessenger; + private name: string; + private codec: MessageCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MessageCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Sends the specified message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param message the message, possibly null. + * @param callback a {@link Reply} callback, possibly null. + */ + send(message: T, callback?: (reply: T)=>void): void { + this.messenger.send(this.name, this.codec.encodeMessage(message), callback == null ? null : new IncomingReplyHandler(callback, this.codec)); + } + + /** + * Registers a message handler on this channel for receiving messages sent from the Flutter + * application. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming message on this channel will be handled + * silently by sending a null reply. + * + * @param handler a {@link MessageHandler}, or null to deregister. + */ + setMessageHandler(handler: MessageHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler(this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + + +export interface Reply { + /** + * Handles the specified message reply. + * + * @param reply the reply, possibly null. + */ + reply: (reply: T) => void; +} + +export interface MessageHandler { + + /** + * Handles the specified message received from Flutter. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply + * handlers. The reply may be submitted asynchronously and invoked on any thread. + * + *

Any uncaught exception thrown by this method, or the preceding message decoding, will be + * caught by the channel implementation and logged, and a null reply message will be sent back + * to Flutter. + * + *

Any uncaught exception thrown during encoding a reply message submitted to the {@link + * Reply} is treated similarly: the exception is logged, and a null reply is sent to Flutter. + * + * @param message the message, possibly null. + * @param reply a {@link Reply} for sending a single message reply back to Flutter. + */ + onMessage(message: T, reply: Reply): void; +} + +class IncomingReplyHandler implements BinaryReply { + private callback: (reply: T)=>void; + private codec: MessageCodec + + constructor(callback:(reply: T)=>void, codec: MessageCodec) { + this.callback = callback + this.codec = codec + } + + reply(reply: ArrayBuffer) { + try { + this.callback(this.codec.decodeMessage(reply)); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message reply", e); + } + } +} + +class IncomingMessageHandler implements BinaryMessageHandler { + private handler: MessageHandler + private codec: MessageCodec + + constructor(handler: MessageHandler, codec: MessageCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, callback: BinaryReply) { + try { + this.handler.onMessage( + this.codec.decodeMessage(message), + { + reply: (reply: T): void => { + callback.reply(this.codec.encodeMessage(reply)); + } + }); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message", e); + callback.reply(null); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..578436417dc4a23cfaf2c5adbb9c8340efa5795d --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using unencoded binary messages, represented as {@link ByteBuffer}s. + * + *

This codec is guaranteed to be compatible with the corresponding BinaryCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, messages are represented using {@code ByteData}. + */ + +export default class BinaryCodec implements MessageCodec { + private returnsDirectByteBufferFromDecoding: boolean = false; + static readonly INSTANCE_DIRECT = new BinaryCodec(true); + + constructor(returnsDirectByteBufferFromDecoding: boolean) { + this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; + } + + encodeMessage(message: ArrayBuffer): ArrayBuffer { + return message + } + + decodeMessage(message: ArrayBuffer): ArrayBuffer { + if (message == null) { + return message; + } else if (this.returnsDirectByteBufferFromDecoding) { + return message; + } else { + return message.slice(0, message.byteLength); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..988c6a57092f7913f20b65bf6afa97b310385931 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * An abstraction over the threading policy used to invoke message handlers. + * + *

These are generated by calling methods like {@link + * BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can be passed into platform + * channels' constructors to control the threading policy for handling platform channels' + * messages. + */ +export interface TaskQueue {} + +/** Options that control how a TaskQueue should operate and be created. */ +export class TaskQueueOptions { + private isSerial = true; + + getIsSerial() { + return this.isSerial; + } + + setIsSerial(isSerial: boolean): TaskQueueOptions { + this.isSerial = isSerial; + return this; + } +} + +/** + * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also + * used in the dual capacity to handle a reply received from Flutter after sending a message. + */ +export interface BinaryReply { + /** + * Handles the specified reply. + * + * @param reply the reply payload, a direct-allocated {@link ByteBuffer} or null. Senders of + * outgoing replies must place the reply bytes between position zero and current position. + * Reply receivers can read from the buffer directly. + */ + reply(reply: ArrayBuffer): void; +} + +/** Handler for incoming binary messages from Flutter. */ +export interface BinaryMessageHandler { + /** + * Handles the specified message. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter + * reply handlers. The reply may be submitted asynchronously. + * + *

Any uncaught exception thrown by this method will be caught by the messenger + * implementation and logged, and a null reply message will be sent back to Flutter. + * + * @param message the message {@link ByteBuffer} payload, possibly null. + * @param reply A {@link BinaryReply} used for submitting a reply back to Flutter. + */ + onMessage(message: ArrayBuffer, reply: BinaryReply): void; +} + +/** + * Facility for communicating with Flutter using asynchronous message passing with binary messages. + * The Flutter Dart code should use BinaryMessages to + * participate. + * + *

{@code BinaryMessenger} is expected to be utilized from a single thread throughout the + * duration of its existence. If created on the main thread, then all invocations should take place + * on the main thread. If created on a background thread, then all invocations should take place on + * that background thread. + * + * @see BasicMessageChannel , which supports message passing with Strings and semi-structured + * messages. + * @see MethodChannel , which supports communication using asynchronous method invocation. + * @see EventChannel , which supports communication using event streams. + */ +export interface BinaryMessenger { + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue; + + /** + * Sends a binary message to the Flutter application. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + */ + send(channel: String, message: ArrayBuffer): void; + + /** + * Sends a binary message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a {@link BinaryReply} callback invoked when the Flutter application responds to + * the message, possibly null. + */ + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void; + + /** + * Registers a handler to be invoked when the Flutter application sends a message to its host + * platform. + * + *

Registration overwrites any previous registration for the same channel name. Use a null + * handler to deregister. + * + *

If no handler has been registered for a particular channel, any incoming message on that + * channel will be handled silently by sending a null reply. + * + * @param channel the name {@link String} of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + * @param taskQueue a {@link BinaryMessenger.TaskQueue} that specifies what thread will execute + * the handler. Specifying null means execute on the platform thread. + */ + //setMessageHandler(channel: String, handler: BinaryMessageHandler) + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void; + // { + // if (taskQueue != null) { + // throw new Error("setMessageHandler called with nonnull taskQueue is not supported.") + // } + // } + + /** + * Enables the ability to queue messages received from Dart. + * + *

This is useful when there are pending channel handler registrations. For example, Dart may + * be initialized concurrently, and prior to the registration of the channel handlers. This + * implies that Dart may start sending messages while plugins are being registered. + */ + enableBufferingIncomingMessages(): void; + // { + // throw new Error("enableBufferingIncomingMessages not implemented."); + // } + + /** + * Disables the ability to queue messages received from Dart. + * + *

This can be used after all pending channel handlers have been registered. + */ + disableBufferingIncomingMessages(): void; + // { + // throw new Error("disableBufferingIncomingMessages not implemented."); + // } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..166659a32e819580f2d433886f763dc453d8a597 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + * A named channel for communicating with the Flutter application using asynchronous event streams. + * + *

Incoming requests for event stream setup are decoded from binary on receipt, and Java + * responses and events are encoded into binary before being transmitted back to Flutter. The {@link + * MethodCodec} used must be compatible with the one used by the Flutter application. This can be + * achieved by creating an EventChannel + * counterpart of this channel on the Dart side. The Java type of stream configuration arguments, + * events, and error details is {@code Object}, but only values supported by the specified {@link + * MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +import Log from '../../util/Log'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; + +const TAG = "EventChannel#"; + +export default class EventChannel { + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec?: MethodCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec ? codec : StandardMethodCodec.INSTANCE + this.taskQueue = taskQueue + } + + + /** + * Registers a stream handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming stream setup requests will be handled + * silently by providing an empty stream. + * + * @param handler a {@link StreamHandler}, or null to deregister. + */ + setStreamHandler(handler: StreamHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger)); + } + } +} + +/** + * Handler of stream setup and teardown requests. + * + *

Implementations must be prepared to accept sequences of alternating calls to {@link + * #onListen(Object, EventChannel.EventSink)} and {@link #onCancel(Object)}. Implementations + * should ideally consume no resources when the last such call is not {@code onListen}. In typical + * situations, this means that the implementation should register itself with platform-specific + * event sources {@code onListen} and deregister again {@code onCancel}. + */ +export interface StreamHandler { + /** + * Handles a request to set up an event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + * @param arguments stream configuration arguments, possibly null. + * @param events an {@link EventSink} for emitting events to the Flutter receiver. + */ + onListen(args: ESObject, events: EventSink): void; + + /** + * Handles a request to tear down the most recently created event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + *

The channel implementation may call this method with null arguments to separate a pair of + * two consecutive set up requests. Such request pairs may occur during Flutter hot restart. Any + * uncaught exception thrown in this situation will be logged without notifying Flutter. + * + * @param arguments stream configuration arguments, possibly null. + */ + onCancel(args: ESObject): void; +} + +/** + * Event callback. Supports dual use: Producers of events to be sent to Flutter act as clients of + * this interface for sending events. Consumers of events sent from Flutter implement this + * interface for handling received events (the latter facility has not been implemented yet). + */ +export interface EventSink { + /** + * Consumes a successful event. + * + * @param event the event, possibly null. + */ + success(event: ESObject): void; + + /** + * Consumes an error event. + * + * @param errorCode an error code String. + * @param errorMessage a human-readable error message String, possibly null. + * @param errorDetails error details, possibly null + */ + error(errorCode: string, errorMessage: string, errorDetails: ESObject): void; + + /** + * Consumes end of stream. Ensuing calls to {@link #success(Object)} or {@link #error(String, + * String, Object)}, if any, are ignored. + */ + endOfStream(): void; +} + +class IncomingStreamRequestHandler implements BinaryMessageHandler { + private handler: StreamHandler; + private activeSink = new AtomicReference(null); + private codec: MethodCodec; + private name: string; + private messenger: BinaryMessenger; + + constructor(handler: StreamHandler, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.handler = handler; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + if (call.method == "listen") { + this.onListen(call.args, reply); + } else if (call.method == "cancel") { + this.onCancel(call.args, reply); + } else { + reply.reply(null); + } + } + + onListen(args: ESObject, callback: BinaryReply): void { + const eventSink = new EventSinkImplementation(this.activeSink, this.name, this.codec, this.messenger); + const oldSink = this.activeSink.getAndSet(eventSink); + if (oldSink != null) { + // Repeated calls to onListen may happen during hot restart. + // We separate them with a call to onCancel. + try { + this.handler.onCancel(null); + } catch (e) { + Log.e(TAG + this.name, "Failed to close existing event stream", e); + } + } + try { + this.handler.onListen(args, eventSink); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + this.activeSink.set(null); + Log.e(TAG + this.name, "Failed to open event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } + + onCancel(args: ESObject, callback: BinaryReply): void { + const oldSink = this.activeSink.getAndSet(null); + if (oldSink != null) { + try { + this.handler.onCancel(args); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + Log.e(TAG + this.name, "Failed to close event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } else { + callback.reply(this.codec.encodeErrorEnvelope("error", "No active stream to cancel", null)); + } + } +} + +class EventSinkImplementation implements EventSink { + private hasEnded = false; + private activeSink: AtomicReference; + private messenger: BinaryMessenger; + private codec: MethodCodec; + private name: string; + + constructor(activeSink: AtomicReference, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.activeSink = activeSink; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + success(event: ESObject): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send(this.name, this.codec.encodeSuccessEnvelope(event)); + } + + error(errorCode: string, errorMessage: string, errorDetails: ESObject) { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send( + this.name, this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + } + + endOfStream(): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.hasEnded = true; + this.messenger.send(this.name, null); + } +} + +class AtomicReference { + private value: T; + + constructor(value: T) { + this.value = value + } + + get(): T { + return this.value; + } + + set(newValue: T): void { + this.value = newValue; + } + + getAndSet(newValue: T) { + const oldValue = this.value; + this.value = newValue; + return oldValue; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets new file mode 100644 index 0000000000000000000000000000000000000000..03af6b520acc908d9cb63914ca2236736218aa77 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterException implements Error { + stack?: string; + message: string; + name: string; + code: string; + details: ESObject + + constructor(code: string, message: string, details: ESObject) { + this.message = message; + this.code = code; + this.details =details; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c289c6054e952a5cf7ed48b58fcfab6e343533b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; +import MethodCodec from './MethodCodec'; +import StringCodec from './StringCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, JSON messages are handled by the JSON facilities of the dart:convert package. + */ +export default class JSONMessageCodec implements MessageCodec { + static INSTANCE = new JSONMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + return StringCodec.INSTANCE.encodeMessage(JSON.stringify(message)); + } + + decodeMessage(message: ArrayBuffer): ESObject { + if (message == null) { + return null; + } + try { + const jsonStr = StringCodec.INSTANCE.decodeMessage(message); + return JSON.parse(jsonStr); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b5bf1d0891fe841d7380e0e6166ca5b82793e7b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import Log from '../../util/Log'; + +import ToolUtils from '../../util/ToolUtils'; +import FlutterException from './FlutterException'; +import JSONMessageCodec from './JSONMessageCodec'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as methods arguments and result payloads are those supported by {@link + * JSONMessageCodec}. + */ +export default class JSONMethodCodec implements MethodCodec { + static INSTANCE = new JSONMethodCodec(); + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + try { + const map: Record = { + "method": methodCall.method, "args": methodCall.args + } + + return JSONMessageCodec.INSTANCE.encodeMessage(map); + } catch (e) { + throw new Error("Invalid JSON"); + } + } + + decodeMethodCall(message: ArrayBuffer): MethodCall { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(message); + if (ToolUtils.isObj(json)) { + const method: string = json["method"]; + const args: ESObject = json["args"]; + if (typeof method == 'string') { + return new MethodCall(method, args); + } + } + throw new Error("Invalid method call: " + json); + } catch (e) { + throw new Error("Invalid JSON:" + JSON.stringify(e)); + } + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([result]); + } + + encodeErrorEnvelope(errorCode: ESObject, errorMessage: string, errorDetails: ESObject) { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(envelope); + if (json instanceof Array) { + if (json.length == 1) { + return json[0]; + } + if (json.length == 3) { + const code: string = json[0]; + const message: string = json[1]; + const details: ESObject = json[2]; + if (typeof code == 'string' && (message == null || typeof message == 'string')) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Invalid envelope: " + json); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..663d57af19c70523e44a5f48cc61e22ab0dc5b33 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * A message encoding/decoding mechanism. + */ +export default interface MessageCodec { + /** + * Encodes the specified message into binary. + */ + encodeMessage(message: T) : ArrayBuffer; + + /** + * Decodes the specified message from binary. + * + */ + decodeMessage(message: ArrayBuffer): T; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets new file mode 100644 index 0000000000000000000000000000000000000000..0042c25c3b21f484cda8158e5485bb57e73dfd82 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import ToolUtils from '../../util/ToolUtils'; +/** Command object representing a method call on a {@link MethodChannel}. */ +export default class MethodCall { + /** The name of the called method. */ + method: string; + + /** + * Arguments for the call. + * + *

Consider using {@link #arguments()} for cases where a particular run-time type is expected. + * Consider using {@link #argument(String)} when that run-time type is {@link Map} or {@link + * JSONObject}. + */ + args: ESObject; + + constructor(method: string, args: ESObject) { + this.method = method + this.args = args + } + + argument(key: string): ESObject { + if (this.args == null) { + return null; + } else if (this.args instanceof Map) { + return (this.args as Map).get(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args[key] + } else { + throw new Error("ClassCastException"); + } + } + + hasArgument(key: string): boolean { + if (arguments == null) { + return false; + } else if (arguments instanceof Map) { + return (this.args as Map).has(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args.hasOwnProperty(key); + } else { + throw new Error("ClassCastException"); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..e491ed5f7fec63ad1064c7e7ddbe468aaf3821df --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; +/** + * A named channel for communicating with the Flutter application using asynchronous method calls. + * + *

Incoming method calls are decoded from binary on receipt, and Java results are encoded into + * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible + * with the one used by the Flutter application. This can be achieved by creating a MethodChannel + * counterpart of this channel on the Dart side. The Java type of method call arguments and results + * is {@code Object}, but only values supported by the specified {@link MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ + +export default class MethodChannel { + static TAG = "MethodChannel#"; + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MethodCodec = StandardMethodCodec.INSTANCE, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Invokes a method on this channel, optionally expecting a result. + * + *

Any uncaught exception thrown by the result callback will be caught and logged. + * + * @param method the name String of the method. + * @param arguments the arguments for the invocation, possibly null. + * @param callback a {@link Result} callback for the invocation result, or null. + */ + invokeMethod(method: string, args: ESObject, callback?: MethodResult): void { + this.messenger.send(this.name, this.codec.encodeMethodCall(new MethodCall(method, args)), callback == null ? null : new IncomingResultHandler(callback, this.codec)); + } + + /** + * Registers a method call handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming method call on this channel will be handled + * silently by sending a null reply. This results in a MissingPluginException + * on the Dart side, unless an OptionalMethodChannel + * is used. + * + * @param handler a {@link MethodCallHandler}, or null to deregister. + */ + setMethodCallHandler(handler: MethodCallHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + +/** A handler of incoming method calls. */ +export interface MethodCallHandler { + /** + * Handles the specified method call received from Flutter. + * + *

Handler implementations must submit a result for all incoming calls, by making a single + * call on the given {@link Result} callback. Failure to do so will result in lingering Flutter + * result handlers. The result may be submitted asynchronously and on any thread. Calls to + * unknown or unimplemented methods should be handled using {@link Result#notImplemented()}. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged, and an error result will be sent back to Flutter. + * + *

The handler is called on the platform thread (Android main thread) by default, or + * otherwise on the thread specified by the {@link BinaryMessenger.TaskQueue} provided to the + * associated {@link MethodChannel} when it was created. See also Threading in + * the Flutter Engine. + * + * @param call A {@link MethodCall}. + * @param result A {@link Result} used for submitting the result of the call. + */ + onMethodCall(call: MethodCall, result: MethodResult): void; +} + +/** + * Method call result callback. Supports dual use: Implementations of methods to be invoked by + * Flutter act as clients of this interface for sending results back to Flutter. Invokers of + * Flutter methods provide implementations of this interface for handling results received from + * Flutter. + * + *

All methods of this class can be invoked on any thread. + */ +export interface MethodResult { + /** + * Handles a successful result. + * + * @param result The result, possibly null. The result must be an Object type supported by the + * codec. For instance, if you are using {@link StandardMessageCodec} (default), please see + * its documentation on what types are supported. + */ + success: (result: ESObject) => void; + + /** + * Handles an error result. + * + * @param errorCode An error code String. + * @param errorMessage A human-readable error message String, possibly null. + * @param errorDetails Error details, possibly null. The details must be an Object type + * supported by the codec. For instance, if you are using {@link StandardMessageCodec} + * (default), please see its documentation on what types are supported. + */ + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) => void; + + /** Handles a call to an unimplemented method. */ + notImplemented: () => void; +} + +class IncomingResultHandler implements BinaryReply { + private callback: MethodResult; + private codec: MethodCodec; + + constructor(callback: MethodResult, codec: MethodCodec) { + this.callback = callback; + this.codec = codec + } + + reply(reply: ArrayBuffer): void { + try { + if (reply == null) { + this.callback.notImplemented(); + } else { + try { + this.callback.success(this.codec.decodeEnvelope(reply)); + } catch (e) { + this.callback.error(e.code, e.getMessage(), e.details); + } + } + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call result", e); + } + } +} + +class IncomingMethodCallHandler implements BinaryMessageHandler { + private handler: MethodCallHandler; + private codec: MethodCodec; + + constructor(handler: MethodCallHandler, codec: MethodCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + try { + this.handler.onMethodCall( + call, { + success: (result: ESObject): void => { + reply.reply(this.codec.encodeSuccessEnvelope(result)); + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject): void => { + reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + }, + + notImplemented: (): void => { + Log.w(MethodChannel.TAG,"method not implemented"); + reply.reply(null); + } + }); + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call", e); + reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..86ed92aca6d512fa8247d963619acf67f29b7fe4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from './MethodCall'; +/** + * A codec for method calls and enveloped results. + * + *

Method calls are encoded as binary messages with enough structure that the codec can extract a + * method name String and an arguments Object. These data items are used to populate a {@link + * MethodCall}. + * + *

All operations throw {@link IllegalArgumentException}, if conversion fails. + */ +export default interface MethodCodec { + /** + * Encodes a message call into binary. + * + * @param methodCall a {@link MethodCall}. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeMethodCall(methodCall: MethodCall): ArrayBuffer; + + /** + * Decodes a message call from binary. + * + * @param methodCall the binary encoding of the method call as a {@link ByteBuffer}. + * @return a {@link MethodCall} representation of the bytes between the given buffer's current + * position and its limit. + */ + decodeMethodCall(methodCall: ArrayBuffer): MethodCall; + + /** + * Encodes a successful result into a binary envelope message. + * + * @param result The result value, possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeSuccessEnvelope(result: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message with the native stacktrace. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @param errorStacktrace Platform stacktrace for the error. possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer + + /** + * Decodes a result envelope from binary. + * + * @param envelope the binary encoding of a result envelope as a {@link ByteBuffer}. + * @return the enveloped result Object. + * @throws FlutterException if the envelope was an error envelope. + */ + decodeEnvelope(envelope: ArrayBuffer): ESObject +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb92c8eb1acc0406e2f14229e8d29d0ef19b3030 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets @@ -0,0 +1,14 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..3de7603e1f576a9af23be11b9f185c67730429b3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets @@ -0,0 +1,310 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * MessageCodec using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMessageCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Supported messages are acyclic values of these forms: + * + *

    + *
  • null + *
  • Booleans + *
  • number + *
  • BigIntegers (see below) + *
  • Int8Array, Int32Array, Float32Array, Float64Array + *
  • Strings + *
  • Array[] + *
  • Lists of supported values + *
  • Maps with supported keys and values + *
+ * + *

On the Dart side, these values are represented as follows: + * + *

    + *
  • null: null + *
  • Boolean: bool + *
  • Byte, Short, Integer, Long: int + *
  • Float, Double: double + *
  • String: String + *
  • byte[]: Uint8List + *
  • int[]: Int32List + *
  • long[]: Int64List + *
  • float[]: Float32List + *
  • double[]: Float64List + *
  • List: List + *
  • Map: Map + *
+ * + *

BigIntegers are represented in Dart as strings with the hexadecimal representation of the + * integer's value. + * + *

To extend the codec, overwrite the writeValue and readValueOfType methods. + */ +export default class StandardMessageCodec implements MessageCodec { + private static TAG = "StandardMessageCodec#"; + static INSTANCE = new StandardMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + const stream = ByteBuffer.from(new ArrayBuffer(1024)) + this.writeValue(stream, message); + return stream.buffer + } + + decodeMessage(message: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(message) + return this.readValue(buffer) + } + + private static NULL = 0; + private static TRUE = 1; + private static FALSE = 2; + private static INT32 = 3; + private static INT64 = 4; + private static BIGINT = 5; + private static FLOAT64 = 6; + private static STRING = 7; + private static UINT8_ARRAY = 8; + private static INT32_ARRAY = 9; + private static INT64_ARRAY = 10; + private static FLOAT64_ARRAY = 11; + private static LIST = 12; + private static MAP = 13; + private static FLOAT32_ARRAY = 14; + + + writeValue(stream: ByteBuffer, value: ESObject): ESObject { + if (value == null || value == undefined) { + stream.writeInt8(StandardMessageCodec.NULL) + } else if (typeof value === "boolean") { + stream.writeInt8(value ? StandardMessageCodec.TRUE : StandardMessageCodec.FALSE) + } else if (typeof value === "number") { + if (Number.isInteger(value)) { //整型 + if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { + stream.writeInt8(StandardMessageCodec.INT32) + stream.writeInt32(value, true) + } else { + stream.writeInt8(StandardMessageCodec.INT64) + stream.writeInt64(value, true) + } + } else { //浮点型 + stream.writeInt8(StandardMessageCodec.FLOAT64) + this.writeAlignment(stream, 8); + stream.writeFloat64(value, true) + } + } else if (typeof value === "string") { + stream.writeInt8(StandardMessageCodec.STRING) + let stringBuff = StringUtils.stringToArrayBuffer(value) + this.writeBytes(stream, new Uint8Array(stringBuff)) + } else if (value instanceof Uint8Array) { + stream.writeInt8(StandardMessageCodec.UINT8_ARRAY) + this.writeBytes(stream, value) + } else if (value instanceof Int32Array) { + stream.writeInt8(StandardMessageCodec.INT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeInt32(item, true)) + } else if (value instanceof Float32Array) { + stream.writeInt8(StandardMessageCodec.FLOAT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeFloat32(item, true)) + } else if (value instanceof Float64Array) { + stream.writeInt8(StandardMessageCodec.FLOAT64_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 8); + value.forEach(item => stream.writeFloat64(item, true)) + } else if (value instanceof Array) { + stream.writeInt8(StandardMessageCodec.LIST) + this.writeSize(stream, value.length); + value.forEach((item: ESObject): void => this.writeValue(stream, item)) + } else if (value instanceof Map) { + stream.writeInt8(StandardMessageCodec.MAP) + this.writeSize(stream, value.size); + value.forEach((value: ESObject, key: ESObject) => { + this.writeValue(stream, key); + this.writeValue(stream, value); + }) + } else if (typeof value == 'object') { + this.writeValue(stream, new Map(value.entries())) + } + return stream + } + + writeAlignment(stream: ByteBuffer, alignment: number) { + let mod: number = stream.byteOffset % alignment; + if (mod != 0) { + for (let i = 0; i < alignment - mod; i++) { + stream.writeInt8(0); + } + } + } + + writeSize(stream: ByteBuffer, value: number) { + if (value < 254) { + stream.writeInt8(value); + } else if (value <= 0xffff) { + stream.writeInt8(254); + stream.writeInt16(value, true); + } else { + stream.writeInt8(255); + stream.writeInt32(value, true); + } + } + + writeBytes(stream: ByteBuffer, bytes: Uint8Array) { + this.writeSize(stream, bytes.length) + bytes.forEach(item => stream.writeInt8(item)) + } + + readSize(buffer: ByteBuffer) { + let value = buffer.readInt8() & 0xff; + if (value < 254) { + return value; + } else if (value == 254) { + return buffer.readInt16(true); + } else { + return buffer.readInt32(true); + } + } + + readAlignment(buffer: ByteBuffer, alignment: number) { + let mod = buffer.byteOffset % alignment; + if (mod != 0) { + buffer.skip(alignment - mod); + } + } + + readValue(buffer: ByteBuffer): ESObject { + let type = buffer.readInt8() + return this.readValueOfType(type, buffer); + } + + readBytes(buffer: ByteBuffer): Uint8Array { + let length = this.readSize(buffer); + let bytes = new Uint8Array(length) + for (let i = 0; i < length; i++) { + bytes[i] = buffer.readUint8() + } + return bytes; + } + + readValueOfType(type: number, buffer: ByteBuffer): ESObject { + let result: ESObject; + switch (type) { + case StandardMessageCodec.NULL: + result = null; + break; + case StandardMessageCodec.TRUE: + result = true; + break; + case StandardMessageCodec.FALSE: + result = false; + break; + case StandardMessageCodec.INT32: + result = buffer.readInt32(true); + break; + case StandardMessageCodec.INT64: + result = buffer.readInt64(true); + break; + case StandardMessageCodec.BIGINT: + result = buffer.readBigInt64(true) + case StandardMessageCodec.FLOAT64: + this.readAlignment(buffer, 8); + result = buffer.readFloat64(true) + break; + case StandardMessageCodec.STRING: { + let bytes = this.readBytes(buffer); + result = StringUtils.arrayBufferToString(bytes.buffer); + break; + } + case StandardMessageCodec.UINT8_ARRAY: { + result = this.readBytes(buffer); + break; + } + case StandardMessageCodec.INT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Int32Array(length) + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt32(true) + } + result = array; + break; + } + case StandardMessageCodec.INT64_ARRAY: { //这里是都城array 还是 bigint待定 + let length = this.readSize(buffer); + let array: Array = new Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt64(true) + } + result = array; + break; + } + case StandardMessageCodec.FLOAT64_ARRAY: { + let length = this.readSize(buffer); + let array = new Float64Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat64(true) + } + result = array; + break; + } + case StandardMessageCodec.LIST: { + let length = this.readSize(buffer); + let array: Array = new Array(length) + for (let i = 0; i < length; i++) { + array[i] = this.readValue(buffer) + } + result = array; + break; + } + case StandardMessageCodec.MAP: { + let size = this.readSize(buffer); + let map: Map = new Map() + for (let i = 0; i < size; i++) { + map.set(this.readValue(buffer), this.readValue(buffer)); + } + result = map; + break; + } + case StandardMessageCodec.FLOAT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Float32Array(length); + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat32(true) + } + result = array; + break; + } + default: + throw new Error("Message corrupted"); + } + return result; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4417c54eb56d55355b73104ee8626a17836735f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import FlutterException from './FlutterException'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMessageCodec from './StandardMessageCodec'; + +/** + * A {@link MethodCodec} using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMethodCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as method arguments and result payloads are those supported by {@link + * StandardMessageCodec}. + */ +export default class StandardMethodCodec implements MethodCodec { + private static TAG = "StandardMethodCodec"; + public static INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE); + + private messageCodec: StandardMessageCodec; + + /** Creates a new method codec based on the specified message codec. */ + constructor(messageCodec: StandardMessageCodec) { + this.messageCodec = messageCodec; + } + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + this.messageCodec.writeValue(stream, methodCall.method); + this.messageCodec.writeValue(stream, methodCall.args); + return stream.buffer; + } + + decodeMethodCall(methodCall: ArrayBuffer): MethodCall { + const buffer = ByteBuffer.from(methodCall); + const method: ESObject = this.messageCodec.readValue(buffer); + const args: ESObject = this.messageCodec.readValue(buffer); + if (typeof method == 'string' && !buffer.hasRemaining()) { + return new MethodCall(method, args); + } + throw new Error("Method call corrupted"); + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(0); + this.messageCodec.writeValue(stream, result); + return stream.buffer; + } + + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + return stream.buffer; + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + this.messageCodec.writeValue(stream, errorStacktrace); + return stream.buffer; + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(envelope); + const flag = buffer.readInt8(); + switch (flag) { + case 0: { + const result: ESObject = this.messageCodec.readValue(buffer); + if (!buffer.hasRemaining()) { + return result; + } + // Falls through intentionally. + } + case 1: { + const code: ESObject = this.messageCodec.readValue(buffer); + const message: ESObject = this.messageCodec.readValue(buffer); + const details: ESObject = this.messageCodec.readValue(buffer); + if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Envelope corrupted"); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..e43be76b5527f6180d9b30ede5c1c07dff84c729 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using UTF-8 encoded String messages. + * + *

This codec is guaranteed to be compatible with the corresponding StringCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + */ +export default class StringCodec implements MessageCodec { + static readonly INSTANCE = new StringCodec(); + + encodeMessage(message: string): ArrayBuffer { + if (message == null) { + return null; + } + return StringUtils.stringToArrayBuffer(message); + } + + decodeMessage(message: ArrayBuffer): string { + if (message == null) { + return null; + } + return StringUtils.arrayBufferToString(message); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets new file mode 100644 index 0000000000000000000000000000000000000000..72735c0a29a1e893e8bf986458cea0da82df0d2b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TextEditState } from '../../embedding/engine/systemchannels/TextInputChannel'; +import Log from '../../util/Log'; +import inputMethod from '@ohos.inputMethod'; +import ArrayList from '@ohos.util.ArrayList'; +import { TextEditingDelta } from './TextEditingDelta'; + +const TAG = "ListenableEditingState"; +export class ListenableEditingState { + //Cache used to storage software keyboard input action + private mStringCache: string; + private mSelectionStartCache: number; + private mSelectionEndCache: number; + private mComposingStartCache: number; + private mComposingEndCache: number; + //used to compare with Cache + private mTextInputState: TextEditState; + private mListeners: ArrayList = new ArrayList(); + private mPendingListeners: ArrayList = new ArrayList(); + private mBatchTextEditingDeltas: ArrayList = new ArrayList(); + private mChangeNotificationDepth: number; + private mBatchEditNestDepth: number; + + private mTextWhenBeginBatchEdit: string; + private mSelectionStartWhenBeginBatchEdit: number; + private mSelectionEndWhenBeginBatchEdit: number; + private mComposingStartWhenBeginBatchEdit: number; + private mComposingEndWhenBeginBatchEdit: number; + + + constructor() { + this.mStringCache = ""; + this.mSelectionStartCache = 0; + this.mSelectionEndCache = 0; + this.mComposingStartCache = -1; + this.mComposingEndCache = -1; + } + + + getSelectionStart(): number { + return this.mSelectionStartCache; + } + + getSelectionEnd(): number { + return this.mSelectionEndCache; + } + + getComposingStart(): number { + return this.mComposingStartCache; + } + + getComposingEnd(): number { + return this.mComposingEndCache; + } + + getStringCache(): string { + return this.mStringCache; + } + + setSelectionStart(newSelectionStart: number): void { + this.mSelectionStartCache = newSelectionStart; + } + + setSelectionEnd(newSelectionEnd: number): void { + this.mSelectionEndCache = newSelectionEnd; + } + + setComposingStart(newComposingStart: number): void { + this.mComposingStartCache = newComposingStart; + } + + setComposingEnd(newComposingEnd: number): void { + this.mComposingEndCache = newComposingEnd; + } + + setStringCache(newStringCache: string): void { + this.mStringCache = newStringCache; + } + + notifyListener(listener: EditingStateWatcher, + textChanged: boolean, + selectionChanged: boolean, + composingChanged: boolean): void { + this.mChangeNotificationDepth++; + listener.didChangeEditingState(textChanged, selectionChanged, composingChanged); + this.mChangeNotificationDepth--; + } + + notifyListenersIfNeeded(textChanged: boolean, selectionChanged: boolean, composingChanged: boolean) { + if (textChanged || selectionChanged || composingChanged) { + for(const listener of this.mListeners) { + this.notifyListener(listener, textChanged, selectionChanged, composingChanged); + } + + } + } + + handleInsertTextEvent(text: string): void { + if(this.mTextInputState == null) { + Log.e(TAG, "mTextInputState is null"); + } + if(this.mStringCache.length == this.mSelectionStartCache) { + //Insert text one by one + this.mStringCache += text; + this.setSelectionStart(this.mStringCache.length); + this.setSelectionEnd(this.mStringCache.length); + + } else if(this.mStringCache.length > this.mSelectionStartCache) { + //Insert text in the middle of string + let tempStr: string = this.mStringCache.substring(0, this.mSelectionStartCache) + text + this.mStringCache.substring(this.mSelectionStartCache); + this.mStringCache = tempStr; + this.mSelectionStartCache += text.length; + this.mSelectionEndCache = this.mSelectionStartCache; + } + if(this.mListeners == null) { + Log.e(TAG, "mListeners is null"); + return; + } + this.notifyListenersIfNeeded(true, true, false); + } + + updateTextInputState(state: TextEditState): void { + this.beginBatchEdit(); + this.setStringCache(state.text); + if(state.hasSelection()) { + this.setSelectionStart(state.selectionStart); + this.setSelectionEnd(state.selectionEnd); + } else { + this.setSelectionStart(0); + this.setSelectionEnd(0); + } + this.endBatchEdit(); + } + + beginBatchEdit(): void { + this.mBatchEditNestDepth++; + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "editing state should not be changed in a listener callback"); + } + if(this.mBatchEditNestDepth == 1 && !this.mListeners.isEmpty()) { + this.mTextWhenBeginBatchEdit = this.getStringCache(); + this.mSelectionStartWhenBeginBatchEdit = this.getSelectionStart(); + this.mSelectionEndWhenBeginBatchEdit = this.getSelectionEnd(); + this.mComposingStartWhenBeginBatchEdit = this.getComposingStart(); + this.mComposingEndWhenBeginBatchEdit = this.getComposingEnd(); + } + } + + endBatchEdit(): void { + if (this.mBatchEditNestDepth == 0) { + Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit"); + return; + } + if(this.mBatchEditNestDepth == 1) { + Log.d(TAG,"mBatchEditNestDepth == 1"); + for(const listener of this.mPendingListeners) { + this.notifyListener(listener, true, true, true); + } + + if(!this.mListeners.isEmpty()) { + Log.d(TAG, "didFinishBatchEdit with " + this.mListeners.length + " listener(s)"); + const textChanged = !(this.mStringCache == this.mTextWhenBeginBatchEdit); + const selectionChanged = this.mSelectionStartWhenBeginBatchEdit != this.getSelectionStart() + || this.mSelectionEndWhenBeginBatchEdit != this.getSelectionEnd(); + const composingRegionChanged = this.mComposingStartWhenBeginBatchEdit != this.getComposingStart() + || this.mComposingEndWhenBeginBatchEdit != this.getComposingEnd(); + Log.d(TAG,"textChanged: " + textChanged + " selectionChanged: " + selectionChanged + + " composingRegionChanged: " + composingRegionChanged); + this.notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged); + } + } + for(const listener of this.mPendingListeners) { + this.mListeners.add(listener); + } + this.mPendingListeners.clear(); + this.mBatchEditNestDepth--; + + } + + addEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "adding a listener " + JSON.stringify(listener) + " in a listener callback"); + } + if(this.mBatchEditNestDepth > 0) { + Log.d(TAG, "a listener was added to EditingState while a batch edit was in progress"); + this.mPendingListeners.add(listener); + } else { + this.mListeners.add(listener); + } + } + + removeEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "removing a listener " + JSON.stringify(listener) + " in a listener callback"); + } + this.mListeners.remove(listener); + if(this.mBatchEditNestDepth > 0) { + this.mPendingListeners.remove(listener); + } + } + + handleDeleteEvent(leftOrRight: boolean, length: number): void { + if(leftOrRight == false) { + //delete left + if(this.mSelectionStartCache == 0) { + return; + } + this.mSelectionStartCache -= length; + let tempStr: string = this.mStringCache.slice(0, this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionStartCache + length); + this.mStringCache = tempStr; + this.mSelectionEndCache = this.mSelectionStartCache; + } else if(leftOrRight == true) { + //delete right + if(this.mSelectionStartCache == this.mStringCache.length) { + return; + } + this.mSelectionEndCache += length; + let tempStr: string = this.mStringCache.slice(0,this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionEndCache); + this.mStringCache = tempStr; + this.mSelectionStartCache = this.mSelectionEndCache; + } + this.notifyListenersIfNeeded(true, true, false); + } + + handleFunctionKey(functionKey: inputMethod.FunctionKey): void { + switch (functionKey.enterKeyType) { + case inputMethod.EnterKeyType.PREVIOUS: + case inputMethod.EnterKeyType.UNSPECIFIED: + case inputMethod.EnterKeyType.NONE: + case inputMethod.EnterKeyType.GO: + case inputMethod.EnterKeyType.SEARCH: + case inputMethod.EnterKeyType.SEND: + case inputMethod.EnterKeyType.NEXT: + case inputMethod.EnterKeyType.DONE: + + } + } + + handleSelectByRange(range: inputMethod.Range): void { + Log.d(TAG, "handleSelectByRange start: " + range.start +" end: " + range.end); + } + + + +} + +export interface EditingStateWatcher { + // Changing the editing state in a didChangeEditingState callback may cause unexpected + // behavior. + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets new file mode 100644 index 0000000000000000000000000000000000000000..c61296f6dae8b30fcb035f72d8457ca36d83a015 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; + +export class TextEditingDelta { + private static TAG = "TextEditingDelta"; + private oldText: string; + private deltaText: string; + private deltaStart: number; + private deltaEnd: number; + private newSelectionStart: number; + private newSelectionEnd: number; + private newComposingStart: number; + private newComposingEnd: number; + + constructor(oldEditable: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number, + replacementDestinationStart?: number, + replacementDestinationEnd?: number, + replacementSource?: string,) { + this.newSelectionStart = selectionStart; + this.newSelectionEnd = selectionEnd; + this.newComposingStart = composingStart; + this.newComposingEnd = composingEnd; + if(replacementDestinationStart === undefined || + replacementDestinationEnd === undefined || + replacementSource === undefined) { + this.setDeltas(oldEditable, "", -1, -1); + } else { + this.setDeltas( + oldEditable, + replacementSource, + replacementDestinationStart, + replacementDestinationEnd); + } + + } + + setDeltas(oldText: string, newText: string, newStart: number, newExtent: number): void { + this.oldText = oldText; + this.deltaText = newText; + this.deltaStart = newStart; + this.deltaEnd = newExtent; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..6df66b9cfde51d0d47c80b693b28f1f049c38b09 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import TextInputChannel, { Configuration, TextEditState, + TextInputMethodHandler, + TextInputType } from '../../embedding/engine/systemchannels/TextInputChannel'; +import inputMethod from '@ohos.inputMethod'; +import Log from '../../util/Log'; +import { EditingStateWatcher, ListenableEditingState } from './ListenableEditingState'; + +export default class TextInputPlugin implements EditingStateWatcher{ + private static TAG = "TextInputPlugin"; + private textInputChannel: TextInputChannel; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private mEditable: ListenableEditingState; + + constructor(textInputChannel: TextInputChannel) { + this.textInputChannel = textInputChannel; + this.mEditable = new ListenableEditingState(); + this.inputMethodController = inputMethod.getController(); + let textInputMethodHandler = new TextInputMethodHandlerImpl(this); + this.textInputChannel.setTextInputMethodHandler(textInputMethodHandler); + } + + public clearTextInputClient() { + this.textInputChannel.textInputMethodHandler.clearClient(); + } + setTextInputEditingState(state: TextEditState) { + + } + + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void { + this.textInputChannel.updateEditingState(this.inputTarget.id, this.mEditable.getStringCache(), + this.mEditable.getSelectionStart(), this.mEditable.getSelectionEnd(), + this.mEditable.getComposingStart(), this.mEditable.getComposingEnd()) + } + + detach(): void { + this.inputMethodController.detach((err) => { + if(err) { + Log.e(TextInputPlugin.TAG, "Failed to detach: " + JSON.stringify(err)); + } + }) + } + +} + +class TextInputMethodHandlerImpl implements TextInputMethodHandler { + private static TAG = "TextInputMethodHandlerImpl"; + private textConfig: inputMethod.TextConfig; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private configuration: Configuration; + private mEditable: ListenableEditingState; + private mRestartInputPending: boolean; + private plugin: EditingStateWatcher; + + private imcFlag: boolean = false; + + constructor(plugin: EditingStateWatcher) { + this.textConfig = { + inputAttribute: { + textInputType: 0, + enterKeyType: 1 + }}; + this.plugin = plugin; + } + + show(): void { + this.showTextInput(); + } + + hide(): void { + this.hideTextInput(); + } + + requestAutofill(): void { + + } + + finishAutofillContext(shouldSave: boolean): void { + + } + + setClient(textInputClientId: number, configuration: Configuration): void { + Log.d(TextInputMethodHandlerImpl.TAG,"textInputClientId: " + textInputClientId); + this.setTextInputClient(textInputClientId, configuration); + } + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void { + + } + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void { + + } + + setEditingState(editingState: TextEditState): void { + Log.d(TextInputMethodHandlerImpl.TAG, "text:" + editingState.text +" selectionStart:" + editingState.selectionStart + " selectionEnd:" + + editingState.selectionEnd + " composingStart:" + editingState.composingStart + " composingEnd" + editingState.composingEnd); + this.mEditable.updateTextInputState(editingState); + } + + clearClient(): void { + this.clearTextInputClient(); + } + + private async showTextInput(): Promise { + await this.attach(true); + if(this.imcFlag != true) { + this.listenKeyBoardEvent(); + } + this.inputMethodController.showTextInput().then(()=> { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in showing softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to show softKeyboard:" + JSON.stringify(err)); + }); + } + + private async hideTextInput(): Promise { + this.inputMethodController.hideTextInput().then(() => { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in hide softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to hide softKeyboard:" + JSON.stringify(err)); + }) + } + + async attach(showKeyboard: boolean): Promise { + try { + await this.inputMethodController.attach(showKeyboard, this.textConfig); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to attach:" + JSON.stringify(err)); + } + } + + setTextInputClient(client: number, configuration: Configuration): void { + this.configuration = configuration; + if(this.canShowTextInput()) { + this.inputTarget = new InputTarget(Type.FRAMEWORK_CLIENT, client); + } else { + this.inputTarget = new InputTarget(Type.NO_TARGET, client); + } + this.mEditable.removeEditingStateListener(this.plugin); + this.mEditable = new ListenableEditingState(); + + this.mRestartInputPending = true; + this.mEditable.addEditingStateListener(this.plugin); + } + + canShowTextInput(): boolean { + if(this.configuration == null || this.configuration.inputType == null) { + return true; + } + return this.configuration.inputType.type != TextInputType.NONE; + } + + listenKeyBoardEvent(): void { + try { + this.inputMethodController.on('insertText', (text) => { + Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); + this.mEditable.handleInsertTextEvent(text); + }); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteLeft', (length) => { + this.mEditable.handleDeleteEvent(false, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteRight', (length) => { + this.mEditable.handleDeleteEvent(true, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('sendFunctionKey', (functionKey) => { + this.mEditable.handleFunctionKey(functionKey); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('selectByRange', (range: inputMethod.Range) => { + this.mEditable.handleSelectByRange(range); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + Log.d(TextInputMethodHandlerImpl.TAG, "listenKeyBoardEvent success"); + this.imcFlag = true; + } + + cancelListenKeyBoardEvent(): void { + this.inputMethodController.off('insertText'); + this.inputMethodController.off('deleteLeft'); + this.inputMethodController.off('deleteRight'); + this.inputMethodController.off('sendFunctionKey'); + this.inputMethodController.off('selectByRange'); + } + + public clearTextInputClient(): void { + if(this.inputTarget.type == Type.VIRTUAL_DISPLAY_PLATFORM_VIEW) { + return; + } + this.mEditable.removeEditingStateListener(this.plugin); + this.configuration = null; + this.inputTarget = new InputTarget(Type.NO_TARGET, 0); + } +} + +enum Type { + NO_TARGET, + // InputConnection is managed by the TextInputPlugin, and events are forwarded to the Flutter + // framework. + FRAMEWORK_CLIENT, + // InputConnection is managed by a platform view that is presented on a virtual display. + VIRTUAL_DISPLAY_PLATFORM_VIEW, + PHYSICAL_DISPLAY_PLATFORM_VIEW, +} + +export class InputTarget { + type: Type; + id: number; + + constructor(type: Type, id: number) { + this.type = type; + this.id = id; + } + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..78ed1c729717344a6e387d3d3dbe62fb4e4df86c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LocalizationChannel, { LocalizationMessageHandler } from '../../embedding/engine/systemchannels/LocalizationChannel' +import common from '@ohos.app.ability.common'; +import intl from '@ohos.intl'; +import Log from '../../util/Log'; +import i18n from '@ohos.i18n'; + +const TAG = "LocalizationPlugin"; +export default class LocalizationPlugin { + private localizationChannel:LocalizationChannel; + private context: common.Context; + + localeFromString(localeString: string): intl.Locale { + localeString = localeString.replace('_','-'); + let parts: string[] = localeString.split('-',-1); + let languageCode = parts[0]; + let scriptCode = ""; + let countryCode = ""; + let index: number = 1; + + if (parts.length > index && parts[index].length == 4) { + scriptCode = parts[index]; + index++; + } + + if (parts.length > index && parts[index].length >= 2 && parts[index].length <= 3) { + countryCode = parts[index]; + index++; + } + return new intl.Locale(languageCode+'-'+ countryCode +'-' + scriptCode); + } + + private localizationMessageHandler: LocalizationMessageHandler =new enterGetStringResource(()=>{ + Log.i(TAG, "getResource enter"); + return "" + }) + constructor(context: common.Context, localizationChannel: LocalizationChannel) { + this.context = context; + this.localizationChannel = localizationChannel; + this.localizationChannel.setLocalizationMessageHandler(this.localizationMessageHandler); + } + + sendLocaleToFlutter(): void { + let systemLanguages = i18n.System.getSystemLanguages(); + this.localizationChannel.sendLocales(systemLanguages); + } +} +class enterGetStringResource{ + getStringResource : (key: string, localeString: string)=>string + + constructor(getStringResource: (key: string, localeString: string)=>string) { + this.getStringResource = getStringResource + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..44c94a11aa2f132f6dd24b3484bb5ca9b59c940c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MouseCursorChannel, { MouseCursorMethodHandler } from '../../embedding/engine/systemchannels/MouseCursorChannel'; +import pointer from '@ohos.multimodalInput.pointer'; +import HashMap from '@ohos.util.HashMap'; +import Log from '../../util/Log'; +import { AsyncCallback } from '@ohos.base'; + +const TAG: string = "MouseCursorPlugin"; +export default class MouseCursorPlugin implements MouseCursorMethodHandler{ + private mView: MouseCursorViewDelegate; + + private mouseCursorChannel: MouseCursorChannel; + + private systemCursorConstants: HashMap; + + constructor(mouseCursorView: MouseCursorViewDelegate, mouseCursorChannel: MouseCursorChannel) { + this.mView = mouseCursorView; + this.mouseCursorChannel = mouseCursorChannel; + this.mouseCursorChannel.setMethodHandler(this); + } + + activateSystemCursor(kind: string): void { + this.mView.getWindowId((error, windowId) => { + if (windowId < 0) { + Log.w(TAG, "set point style failed windowId is invalid"); + return; + } + let pointStyle: pointer.PointerStyle = this.resolveSystemCursor(kind); + try { + pointer.setPointerStyle(windowId, pointStyle, (err: ESObject) => { + Log.i(TAG, "set point style success kind : " + kind); + }) + } catch (e) { + Log.e(TAG, "set point style failed : " + kind + " " + JSON.stringify(e)); + } + }); + } + + /** + * Return mouse cursor point style + * + *

This method guarantees to return a non-null object. + * + * @param kind mouse cursor type + * @returns point style + */ + private resolveSystemCursor(kind: string): pointer.PointerStyle { + if (this.systemCursorConstants == null) { + this.systemCursorConstants = new HashMap(); + this.systemCursorConstants.set("alias", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("allScroll", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("basic", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("cell", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("click", pointer.PointerStyle.HAND_POINTING); + this.systemCursorConstants.set("contextMenu", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("copy", pointer.PointerStyle.CURSOR_COPY); + this.systemCursorConstants.set("forbidden", pointer.PointerStyle.CURSOR_FORBID); + this.systemCursorConstants.set("grab", pointer.PointerStyle.HAND_OPEN); + this.systemCursorConstants.set("grabbing", pointer.PointerStyle.HAND_GRABBING); + this.systemCursorConstants.set("help", pointer.PointerStyle.HELP); + this.systemCursorConstants.set("move", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("none", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("noDrop", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("precise", pointer.PointerStyle.CROSS); + this.systemCursorConstants.set("text", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("resizeColum", pointer.PointerStyle.NORTH_SOUTH); + this.systemCursorConstants.set("resizeDown", pointer.PointerStyle.SOUTH); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeDownRight", pointer.PointerStyle.SOUTH_EAST); + this.systemCursorConstants.set("resizeLeft", pointer.PointerStyle.WEST); + this.systemCursorConstants.set("resizeLeftRight", pointer.PointerStyle.RESIZE_LEFT_RIGHT); + this.systemCursorConstants.set("resizeRight", pointer.PointerStyle.EAST); + this.systemCursorConstants.set("resizeRow", pointer.PointerStyle.WEST_EAST); + this.systemCursorConstants.set("resizeUp", pointer.PointerStyle.NORTH); + this.systemCursorConstants.set("resizeUpDown", pointer.PointerStyle.RESIZE_UP_DOWN); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeUpRight", pointer.PointerStyle.NORTH_EAST); + this.systemCursorConstants.set("resizeUpLeftDownRight", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("resizeUpRightDownLeft", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("verticalText", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("wait", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("zoomIn", pointer.PointerStyle.ZOOM_IN); + this.systemCursorConstants.set("zoomOut", pointer.PointerStyle.ZOOM_OUT); + } + let pointStyle:pointer.PointerStyle = this.systemCursorConstants.get(kind); + if (pointStyle === null) { + return pointer.PointerStyle.DEFAULT; + } + return pointStyle; + } + + /** + * Detaches the text input plugin from the platform views controller; + * + *

The MouseCursorPlugin instance should not be used after call this. + */ + destroy(): void { + this.mouseCursorChannel.setMethodHandler(null); + } +} + +/** + * Delegate interface for requesting the system to display a pointer icon object. + * + *

Typically implemented by an component, such as a{@code FlutterView} + */ +export interface MouseCursorViewDelegate { + /** + * get window id to set mouse style + *

component need to implement this interface to get windowId + * + * @param callback windowId + * */ + getWindowId(callback: AsyncCallback): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..faa3bc90e50c304744883689a532d0dc323bd714 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export class AccessibilityEventsDelegate { + private accessibilityBridge: AccessibilityBridge; + + requestSendAccessibilityEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + onAccessibilityHoverEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + setAccessibilityBridge (accessibilityBridge: AccessibilityBridge): void { + this.accessibilityBridge = accessibilityBridge; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets new file mode 100644 index 0000000000000000000000000000000000000000..64e8c7f780dc9253f3fd79c05663805a13c8d839 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; + +export class PlatformOverlayView { + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + + constructor(context: Context, width: Number, height: Number, accessibilityEventsDelegate: AccessibilityEventsDelegate) { + this.accessibilityEventsDelegate= accessibilityEventsDelegate; + } + + public onHoverEvent(): boolean { + return false; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets new file mode 100644 index 0000000000000000000000000000000000000000..ddf5f59a71c4d1c7d51082bcf104990e0faa08c6 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DynamicView } from '../../view/DynamicView/dynamicView' + +/** A handle to an DynamicView to be embedded in the Flutter hierarchy. */ +export default abstract class PlatformView { + /** Returns the DynamicView to be embedded in the Flutter hierarchy. */ + abstract getView(): DVModel; + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is + * associated with the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} can now + * render a UI and interact with the user. + * + *

Some platform views may have unusual dependencies on the {@link View} that renders Flutter + * UIs, such as unique keyboard interactions. That {@link View} is provided here for those + * purposes. Use of this {@link View} should be avoided if it is not absolutely necessary, because + * depending on this {@link View} will tend to make platform view code more brittle to future + * changes. + */ + onFlutterViewAttached(dvModel: DVModel): void {} + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is detached + * and disassociated from the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} no longer + * has a rendering surface, or a user interaction surface of any kind. + * + *

This platform view must release any references related to the DynamicView that was + * provided in {@link #onFlutterViewAttached(View)}. + */ + onFlutterViewDetached(): void {} + + /** + * Dispose this platform view. + * + *

The {@link PlatformView} object is unusable after this method is called. + * + *

Plugins implementing {@link PlatformView} must clear all references to the View object and + * the PlatformView after this method is called. Failing to do so will result in a memory leak. + * + *

References related to the DynamicView attached in {@link + * #onFlutterViewAttached(View)} must be released in {@code dispose()} to avoid memory leaks. + */ + abstract dispose(): void; + + /** + * Callback fired when the platform's input connection is locked, or should be used. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionLocked(): void {} + + /** + * Callback fired when the platform input connection has been unlocked. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionUnlocked(): void {} +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..373a7ea5a5906c812c330762fd3825d4ce420201 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from '../common/MessageCodec'; +import PlatformView from './PlatformView' +import common from '@ohos.app.ability.common'; + +export default abstract class PlatformViewFactory { + private createArgsCodec: MessageCodec; + + /** @param createArgsCodec the codec used to decode the args parameter of {@link #create}. */ + constructor(createArgsCodec: MessageCodec) { + this.createArgsCodec = createArgsCodec; + } + + /** + * Creates a new Dynamic be embedded in the Flutter hierarchy. + * + * @param context the context to be used when creating the view, this is different than + * FlutterView's context. + * @param viewId unique identifier for the created instance, this value is known on the Dart side. + * @param args arguments sent from the Flutter app. The bytes for this value are decoded using the + * createArgsCodec argument passed to the constructor. This is null if createArgsCodec was + * null, or no arguments were sent from the Flutter app. + */ + public abstract create(context: common.Context, viewId: number, args: ESObject): PlatformView; + + /** Returns the codec to be used for decoding the args parameter of {@link #create}. */ + getCreateArgsCodec(): MessageCodec { + return this.createArgsCodec; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c49f5eeaddb54cece120df8eea307c69ad76ebf --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PlatformViewFactory from './PlatformViewFactory' + +/** + * Registry for platform view factories. + * + *

Plugins can register factories for specific view types. + */ +export default interface PlatformViewRegistry { + /** + * Registers a factory for a platform view. + * + * @param viewTypeId unique identifier for the platform view's type. + * @param factory factory for creating platform views of the specified type. + * @return true if succeeded, false if a factory is already registered for viewTypeId. + */ + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets new file mode 100644 index 0000000000000000000000000000000000000000..98cb247d890cbe65150feb84242c01128047e7f9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import PlatformViewFactory from './PlatformViewFactory' +import PlatformViewRegistry from './PlatformViewRegistry' + +export default class PlatformViewRegistryImpl implements PlatformViewRegistry { + // Maps a platform view type id to its factory. + private viewFactories: HashMap; + + constructor() { + this.viewFactories = new HashMap(); + } + + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { + if (this.viewFactories.hasKey(viewTypeId)) { + return false; + } + + this.viewFactories.set(viewTypeId, factory); + return true; + } + + getFactory(viewTypeId: string): PlatformViewFactory { + return this.viewFactories.get(viewTypeId); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..c34d9bcce565e65f3eebb5cccf355a9d3f366fac --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor'; +import { DVModel, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; +import { RootDvModeManager } from './RootDvModelManager'; +import matrix4 from '@ohos.matrix4' +import Log from '../../util/Log'; + +const TAG: string = "PlatformViewWrapper"; +export class PlatformViewWrapper { + private prevLeft: number; + private prevTop: number; + private left: number; + private top: number; + private bufferWidth: number; + private bufferHeight: number; + private touchProcessor: OhosTouchProcessor; + + // private onTouch = (touchEvent: TouchEvent) => { + // switch (touchEvent.type) { + // case TouchType.Down: + // this.prevLeft = this.left; + // this.prevTop = this.top; + // this.model.params.translateX = this.left; + // this.model.params.translateY = this.top; + // break; + // case TouchType.Move: + // this.model.params.translateX = this.prevLeft; + // this.model.params.translateY = this.prevTop; + // this.prevLeft = this.left; + // this.prevTop = this.top; + // break; + // case TouchType.Up: + // case TouchType.Cancel: + // default: + // break; + // } + // } + + private model : DVModel = createDVModelFromJson( new DVModelParam("Column", [])); + + public setTouchProcessor(newTouchProcessor: OhosTouchProcessor): void { + this.touchProcessor = newTouchProcessor; + } + + constructor() { + } + + public getDvModel(): DVModel { + return this.model; + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + + public setLayoutParams(parameters : DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + this.setParams(this.model.params, "marginLeft", this.getParams(parameters, "marginLeft")); + this.setParams(this.model.params, "marginTop", this.getParams(parameters, "marginTop")); + this.left = this.getParams(parameters, "marginLeft"); + this.top = this.getParams(parameters, "marginTop"); + + this.setParams(this.model.params, "width", this.getParams(parameters, "width")); + this.setParams(this.model.params, "height", this.getParams(parameters, "height")); + + // this.model.params.marginLeft = parameters.marginLeft; + // this.model.params.marginTop = parameters.marginTop; + // this.left = parameters.marginLeft; + // this.top = parameters.marginTop;; + + // this.model.params.width = parameters.width; + // this.model.params.height = parameters.height; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } +} + +class DVModelParam { + compType: string + children: [] + + constructor(compType: string, children: []) { + this.compType = compType; + this.children = children; + } +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..62888046c561533a3ea096c77ce7f3f634503e4c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export interface PlatformViewsAccessibilityDelegate { + /** + * Returns the root of the view hierarchy for the platform view with the requested id, or null if + * there is no corresponding view. + */ + getPlatformViewById(viewId: number): Object; + + /** Returns true if the platform view uses virtual displays. */ + usesVirtualDisplay(id: number): boolean; + + /** + * Attaches an accessibility bridge for this platform views accessibility delegate. + * + *

Accessibility events originating in platform views belonging to this delegate will be + * delegated to this accessibility bridge. + */ + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void; + + /** + * Detaches the current accessibility bridge. + * + *

Any accessibility events sent by platform views belonging to this delegate will be ignored + * until a new accessibility bridge is attached. + */ + detachAccessibilityBridge(): void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets new file mode 100644 index 0000000000000000000000000000000000000000..b77917fc75a9baaf6c7f88a4df6fd4349a5b789c --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { PlatformViewsAccessibilityDelegate } from './PlatformViewsAccessibilityDelegate'; +import PlatformViewsChannel, { + PlatformViewBufferResized, + PlatformViewCreationRequest, + PlatformViewResizeRequest, + PlatformViewsHandler, PlatformViewTouch, PlatformViewBufferSize +} from '../../../ets/embedding/engine/systemchannels/PlatformViewsChannel'; +import PlatformView from './PlatformView'; +import { DVModel, DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import display from '@ohos.display'; +import { FlutterView } from '../../view/FlutterView'; +import { TextureRegistry } from '../../view/TextureRegistry'; +import TextInputPlugin from '../editing/TextInputPlugin'; +import { PlatformOverlayView } from './PlatformOverlayView'; +import { PlatformViewWrapper } from './PlatformViewWrapper'; +import { FlutterOverlaySurface } from '../../embedding/engine/FlutterOverlaySurface'; +import HashSet from '@ohos.util.HashSet'; +import PlatformViewRegistry from './PlatformViewRegistry'; +import PlatformViewRegistryImpl from './PlatformViewRegistryImpl'; +import DartExecutor from '../../embedding/engine/dart/DartExecutor'; +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; +import AccessibilityBridge from '../../view/AccessibilityBridge'; +import { RootDvModeManager } from './RootDvModelManager'; +import { FlutterMutatorView } from '../../embedding/engine/mutatorsstack/FlutterMutatorView'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log' +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor' +import PlatformViewFactory from './PlatformViewFactory' +import { ByteBuffer } from '../../util/ByteBuffer'; + +const TAG = "PlatformViewsController" + +export default class PlatformViewsController implements PlatformViewsAccessibilityDelegate, PlatformViewsHandler { + private registry: PlatformViewRegistryImpl; + private context: Context; + private flutterView: FlutterView; + private textureRegistry: TextureRegistry; + private textInputPlugin: TextInputPlugin; + private platformViewsChannel: PlatformViewsChannel; + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + private nextOverlayLayerId: number = 0; + private ohosTouchProcessor: OhosTouchProcessor; + private usesSoftwareRendering: boolean = false; + + private platformViews: Map; + private overlayLayerViews: Map; + private viewWrappers: Map; + private currentFrameUsedOverlayLayerIds: HashSet; + private currentFrameUsedPlatformViewIds: HashSet; + private rootDvModel = RootDvModeManager.getRootDvMode(); + private platformViewParent: Map; + + constructor() { + this.registry = new PlatformViewRegistryImpl(); + this.accessibilityEventsDelegate = new AccessibilityEventsDelegate(); + this.overlayLayerViews = new Map(); + this.currentFrameUsedOverlayLayerIds = new HashSet(); + this.currentFrameUsedPlatformViewIds = new HashSet(); + this.viewWrappers = new Map(); + this.platformViews = new Map(); + this.platformViewParent = new Map(); + } + + + getPlatformViewById(viewId: number): Object { + throw new Error('Method not implemented.'); + } + + usesVirtualDisplay(id: number): boolean { + throw new Error('Method not implemented.'); + } + + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void { + throw new Error('Method not implemented.'); + } + + detachAccessibilityBridge(): void { + throw new Error('Method not implemented.'); + } + + createForPlatformViewLayer(request: PlatformViewCreationRequest): void { + Log.i(TAG, "Enter createForPlatformViewLayer"); + this.ensureValidRequest(request); + + let platformView: PlatformView = this.createPlatformView(request, false); + + this.configureForHybridComposition(platformView, request); + } + + dispose(viewId: number): void { + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Disposing unknown platform view with id: " + viewId); + return; + } + this.platformViews.delete(viewId); + + try { + platformView.dispose(); + } catch (err) { + Log.e(TAG, "Disposing platform view threw an exception", err); + } + + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper != null) { + this.viewWrappers.delete(viewId); + } + + let parentView: FlutterMutatorView = this.platformViewParent.get(viewId); + if (parentView != null) { + this.platformViewParent.delete(viewId); + } + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void { + let physicalWidth: number = this.toPhysicalPixels(request.newLogicalWidth); + let physicalHeight: number = this.toPhysicalPixels(request.newLogicalHeight); + let viewId: number = request.viewId; + Log.i(TAG, `Resize viewId ${viewId}, pw:${physicalWidth}, ph:${physicalHeight},lw:${request.newLogicalWidth}, lh:${request.newLogicalHeight}`); + + let platformView: PlatformView = this.platformViews.get(viewId); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (platformView == null || viewWrapper == null) { + Log.e(TAG, "Resizing unknown platform view with id: " + viewId); + return; + } + + let viewWrapperLayoutParams: DVModelParameters = viewWrapper.getDvModel().getLayoutParams(); + if (physicalWidth) { + this.setParams(viewWrapperLayoutParams, "width", physicalWidth); + // viewWrapperLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(viewWrapperLayoutParams, "height", physicalHeight); + // viewWrapperLayoutParams.height = physicalHeight; + } + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView != null) { + let embeddedViewLayoutParams = embeddedView.getLayoutParams(); + if (physicalWidth) { + this.setParams(embeddedViewLayoutParams, "width", physicalWidth); + // embeddedViewLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(embeddedViewLayoutParams, "height", physicalHeight); + // embeddedViewLayoutParams.height = physicalHeight; + } + } + + onComplete.run(new PlatformViewBufferSize(request.newLogicalWidth, request.newLogicalHeight)); + } + + offset(viewId: number, top: number, left: number): void { + Log.i(TAG, `Offset is id${viewId}, t:${top}, l:${left}`); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper == null) { + Log.e(TAG, "Setting offset for an unknown platform view with id: " + viewId); + return; + } + + let physicalTop = this.toPhysicalPixels(top); + let physicalLeft = this.toPhysicalPixels(left); + let params = viewWrapper.getDvModel().params; + this.setParams(params, "marginTop", physicalTop); + this.setParams(params, "marginLeft", physicalLeft); + // params.marginTop = physicalTop; + // params.marginLeft = physicalLeft; + viewWrapper.setLayoutParams(params); + } + + onTouch(touch: PlatformViewTouch): void { + let viewId: number = touch.viewId; + let density: number = display.getDefaultDisplaySync().densityDPI; + + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Sending touch to an unknown platform view with id: " + viewId); + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + Log.e(TAG, "Sending touch to a null dv model with id: " + viewId); + } + Log.e(TAG, "Sending touch to a dv model with id: " + viewId.toString()); + sendEventByKey(viewId.toString(), 10, ""); + } + + setDirection(viewId: number, direction: number): void { + if (!this.validateDirection(direction)) { + throw new Error("Trying to set unknown direction value: " + + direction + + "(view id: " + + viewId + + ")"); + } + + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + this.setParams(embeddedView.params, "direction", direction); + // embeddedView.params.direction = direction; + } + + validateDirection(direction:number):boolean { + return direction == Direction.Ltr || direction == Direction.Rtl || direction == Direction.Auto; + } + + clearFocus(viewId: number): void { + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + focusControl.requestFocus("flutterXComponent"); + } + synchronizeToNativeViewHierarchy(yes: boolean): void { + throw new Error('Method not implemented.'); + } + + public createForTextureLayer(request: PlatformViewCreationRequest): number { + Log.i(TAG, "Enter createForTextureLayer"); + this.ensureValidRequest(request); + + let viewId: number = request.viewId; + if (this.viewWrappers.get(request.viewId) != null) { + throw new Error( + "Trying to create an already created platform view, view id: " + viewId); + } + + let platformView: PlatformView = this.createPlatformView(request, true); + let dynamicView: DVModel = platformView.getView(); + return this.configureForTextureLayerComposition(platformView, request); + } + + private ensureValidRequest(request: PlatformViewCreationRequest): void { + if (!this.validateDirection(request.direction)) { + throw new Error("Trying to create a view with unknown direction value: " + + request.direction + + "(view id: " + + request.viewId + + ")") + } + } + + private createPlatformView(request: PlatformViewCreationRequest, wrapContext: boolean): PlatformView { + Log.i(TAG, "Enter createPlatformView"); + const viewFactory: PlatformViewFactory = this.registry.getFactory(request.viewType); + if (viewFactory == null) { + throw new Error("Trying to create a platform view of unregistered type: " + request.viewType) + } + + let createParams: ESObject = null; + if (request.params != null) { + let byteParas : ByteBuffer = request.params as ByteBuffer; + createParams = viewFactory.getCreateArgsCodec().decodeMessage(byteParas.buffer); + } + + let mutableContext: common.Context = this.context; + let platformView = viewFactory.create(mutableContext, request.viewId, createParams); + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView == null) { + throw new Error("PlatformView#getView() returned null, but an dynamic view reference was expected."); + } + + this.setParams(embeddedView.params, "direction", request.direction); + // embeddedView.params.direction = request.direction; + + this.platformViews.set(request.viewId, platformView); + return platformView; + } + + // Configures the view for Hybrid Composition mode. + private configureForHybridComposition(platformView: PlatformView, request: PlatformViewCreationRequest): void { + Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId); + } + + private configureForTextureLayerComposition(platformView: PlatformView, request: PlatformViewCreationRequest): number { + Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId); + + let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); + let textureId: number = 0; + + let physicalTop: number = this.toPhysicalPixels(request.logicalTop); + let physicalLeft: number = this.toPhysicalPixels(request.logicalLeft); + + Log.i(TAG, `View pW:${request.logicalWidth}, pH:${request.logicalHeight}, pT:${physicalTop}, pL:${physicalLeft}`); + + let param: DVModelParameters = new DVModelParameters(); + + this.setParams(param, "marginLeft", physicalLeft); + this.setParams(param, "marginTop", physicalTop); + // param.marginLeft = physicalLeft; + // param.marginTop = physicalTop; + + let model = platformView.getView(); + if (request.logicalWidth != null) { + let physicalWidth: number = this.toPhysicalPixels(request.logicalWidth); + this.setParams(model.params, "width", physicalWidth); + this.setParams(param, "width", physicalWidth); + // model.params.width = physicalWidth; + // param.width = physicalWidth; + } + + if (request.logicalHeight != null) { + let physicalHeight: number = this.toPhysicalPixels(request.logicalHeight); + this.setParams(model.params, "height", physicalHeight); + this.setParams(param, "height", physicalHeight); + // model.params.height = physicalHeight; + // param.height = physicalHeight; + } + + viewWrapper.setLayoutParams(param); + viewWrapper.addDvModel(model); + + RootDvModeManager.addDvModel(viewWrapper.getDvModel()); + this.viewWrappers.set(request.viewId, viewWrapper); + Log.i(TAG, "Create platform view success"); + + return textureId; + } + + public attach(context: Context, textureRegistry: TextureRegistry, dartExecutor: DartExecutor): void { + if (this.context != null) { + + } + this.context = context; + this.textureRegistry = textureRegistry; + this.platformViewsChannel = new PlatformViewsChannel(dartExecutor); + this.platformViewsChannel.setPlatformViewsHandler(this); + } + + public detach(): void { + if (this.platformViewsChannel != null) { + this.platformViewsChannel.setPlatformViewsHandler(null); + } + this.destroyOverlaySurfaces(); + this.platformViewsChannel = null; + this.context = null; + this.textureRegistry = null; + } + + public attachToView() { + for (let wrapper of this.viewWrappers.values()) { + this.rootDvModel.model.children.push(wrapper.getDvModel()); + } + for (let mutator of this.platformViewParent.values()) { + this.rootDvModel.model.children.push(mutator.getDvModel()); + } + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewAttached(this.rootDvModel.model); + } + } + + public detachFromView(): void { + for (let index = 0; index < this.viewWrappers.size; index++) { + this.rootDvModel.model.children.pop(); + } + for (let index = 0; index < this.platformViewParent.size; index++) { + this.rootDvModel.model.children.pop(); + } + this.destroyOverlaySurfaces(); + this.removeOverlaySurfaces(); + this.rootDvModel = null; + + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewDetached(); + } + } + + public attachTextInputPlugin(textInputPlugin: TextInputPlugin): void { + this.textInputPlugin = textInputPlugin; + } + + public detachTextInputPlugin(): void { + this.textInputPlugin == null; + } + + public getRegistry(): PlatformViewRegistry { + return this.registry; + } + + public onDetachedFromNapi(): void { + this.diposeAllViews(); + } + + public onPreEngineRestart(): void { + this.diposeAllViews(); + } + + private getDisplayDensity(): number { + return display.getDefaultDisplaySync().densityPixels; + } + private toPhysicalPixels(logicalPixels: number): number { + return Math.round(px2vp(logicalPixels * this.getDisplayDensity())); + } + + private toLogicalPixelsByDensity(physicalPixels: number, displayDensity: number): number { + return Math.round(physicalPixels / displayDensity); + } + + private toLogicalPixels(physicalPixels: number): number { + return this.toLogicalPixelsByDensity(physicalPixels, this.getDisplayDensity()); + } + + + private diposeAllViews(): void { + } + + private initializeRootImageViewIfNeeded(): void { + } + + initializePlatformViewIfNeeded(viewId: number): void { + let platformView: PlatformView = this.platformViews[viewId]; + if (platformView == null) { + throw new Error("Platform view hasn't been initialized from the platform view channel."); + } + if (this.platformViewParent[viewId] == null) { + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + throw new Error("PlatformView#getView() returned null, but an ohos dv model reference was expected."); + } + let parentView: FlutterMutatorView = new FlutterMutatorView(); + parentView.setOnDescendantFocusChangeListener(() => { + this.platformViewsChannel.invokeViewFocused(viewId); + }, () => { + if (this.textInputPlugin != null) { + this.textInputPlugin.clearTextInputClient(); + } + }); + } + + public onDisplayOverlaySurface(id: number, x: number, y: number, width: number, height: number): void { + } + + public onBeginFrame(): void { + this.currentFrameUsedOverlayLayerIds.clear(); + this.currentFrameUsedPlatformViewIds.clear(); + } + + public onEndFrame(): void { + } + + private finishFrame(isFrameRenderedUsingImageReaders: boolean): void { + } + + public createOverlaySurfaceByPlatformOverlayView(imageView: PlatformOverlayView) { + let id = this.nextOverlayLayerId++; + this.overlayLayerViews.set(id, imageView); + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + public createOverlaySurface(): FlutterOverlaySurface { + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + private destroyOverlaySurfaces(): void { + } + + private removeOverlaySurfaces(): void { + if (!(this.flutterView instanceof FlutterView)) { + return; + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cc2cb0b2cc44032d2384282013785d150162bc9 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DVModelContainer, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +@Component +struct XComponentStruct { + private context: ESObject; + + build() { + XComponent({ id: 'flutterXComponent', type: 'texture', libraryname: 'flutter' }) + .onLoad((context) => { + this.context = context; + }) + .onDestroy(() => { + }) + } +} + +interface $$type { + param: DVModelParameters +} + +@Builder +function BuildXComponentStruct($$: $$type) { + XComponentStruct(); +} + +class DVModelJson { + compType: string + children: Array + attributes: ESObject + + constructor(compType: string, children: Array, attributes: ESObject) { + this.compType = compType + this.children = children + this.attributes = attributes + } +} + +export class RootDvModeManager { + private static xComponentModel: ESObject = + { + compType: "xComponent", + build: BuildXComponentStruct + }; + private static model: DVModel = createDVModelFromJson(new DVModelJson("Stack", [RootDvModeManager.xComponentModel], { + alignContent: Alignment.TopStart + },) + + ); + private static container: DVModelContainer = new DVModelContainer(RootDvModeManager.model); + + public static getRootDvMode(): DVModelContainer { + return RootDvModeManager.container; + } + + public static addDvModel(model: DVModel): void { + RootDvModeManager.container.model.children.push(model); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets new file mode 100644 index 0000000000000000000000000000000000000000..99a7d4b522caa6daf09b06e6feb40bcd6203abd3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * A byte buffer. + * + * Supports the following data types: + * - Bool + * - Int (8, 16, 32, 64) + * - Uint (8, 16, 32, 64) + * - BigInt (64) + * - String (utf8, utf16, and delimited) + * - TypedArray + * + */ +export class ByteBuffer { + + /** + * Creates a byte buffer. + * @param source The data source. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns A byte buffer. + */ + static from(source: ArrayBuffer, byteOffset?: number, byteLength?: number): ByteBuffer { + // if (ArrayBuffer.isView(source)) { + // byteOffset = source.byteOffset + (byteOffset || 0) + // } + const byteBuffer = new ByteBuffer() + byteBuffer.dataView = byteLength === undefined ? new DataView(source, byteOffset) : new DataView(source, byteOffset, Math.min(source.byteLength, byteLength)) + byteBuffer.mByteOffset = byteBuffer.dataView.byteOffset + return byteBuffer + } + + /** + * The dataView. + */ + private dataView: DataView + + /** + * The byte offset. + */ + mByteOffset: number = 0 + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteOffset(): number { + return this.mByteOffset + } + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteLength(): number { + return this.dataView.byteLength + } + + /** + * The number of remaining bytes. + * @returns The number of bytes remaining. + */ + get bytesRemaining(): number { + return this.dataView.byteLength - this.mByteOffset + } + + hasRemaining(): boolean { + return this.mByteOffset < this.dataView.byteLength; + } + + get buffer(): ArrayBuffer { + const dataBuffer = new DataView(new ArrayBuffer(this.mByteOffset)); + for (let i = 0; i < this.mByteOffset; i++) { + dataBuffer.setUint8(i, this.dataView.getUint8(i)); + } + return dataBuffer.buffer + } + + /** + * Skips the byte offset. + * @param byteLength The byte length. + */ + skip(byteLength: number): void { + this.mByteOffset += byteLength + } + + /** + * Resets the byte offset. + */ + reset(): void { + this.mByteOffset = this.dataView.byteOffset + } + + /** + * Clears the byte buffer. + */ + clear(): void { + this.getUint8Array(0).fill(0) + } + + /** + * check buffer capacity. + */ + checkWriteCapacity(slen: number): void { + if (this.mByteOffset + slen > this.dataView.byteLength) { + let checkBuffer = new DataView(new ArrayBuffer(this.dataView.byteLength + slen + 512)); + for (let i = 0; i < this.mByteOffset; i++) { + checkBuffer.setUint8(i, this.dataView.getUint8(i)); + } + this.dataView = checkBuffer; + } + } + + /** + * Gets a boolean. + * @param byteOffset The byte offset. + */ + getBool(byteOffset: number): boolean { + return this.getInt8(byteOffset) !== 0 + } + + /** + * Reads the next boolean. + */ + readBool(): boolean { + return this.getInt8(this.mByteOffset++) !== 0 + } + + /** + * Sets a boolean. + * @param byteOffset The byte offset. + * @param value The value. + */ + setBool(byteOffset: number, value: boolean): void { + this.dataView.setInt8(byteOffset, value ? 1 : 0) + } + + /** + * Writes the next boolean. + * @param value The value. + */ + writeBool(value: boolean): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value ? 1 : 0) + } + + /** + * Gets an signed byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getInt8(byteOffset: number): number { + return this.dataView.getInt8(byteOffset) + } + + /** + * Reads the next signed byte. + * @returns The value. + */ + readInt8(): number { + return this.getInt8(this.mByteOffset++) + } + + /** + * Sets a signed byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setInt8(byteOffset: number, value: number): void { + this.dataView.setInt8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeInt8(value: number): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value) + } + + /** + * Gets an unsigned byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getUint8(byteOffset: number): number { + return this.dataView.getUint8(byteOffset) + } + + /** + * Reads the next unsigned byte. + * @returns The value. + */ + readUint8(): number { + return this.getUint8(this.mByteOffset++) + } + + /** + * Sets an unsigned byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8(byteOffset: number, value: number): void { + this.dataView.setUint8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeUint8(value: number): void { + this.checkWriteCapacity(1) + this.setUint8(this.mByteOffset++, value) + } + + /** + * Gets an signed short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt16(byteOffset, littleEndian) + } + + /** + * Reads the next signed short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt16(littleEndian?: boolean): number { + const value = this.getInt16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets a signed short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setInt16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an unsigned short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint16(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint16(littleEndian?: boolean): number { + const value = this.getUint16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets an unsigned short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setUint16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an signed integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt32(byteOffset, littleEndian) + } + + /** + * Reads the next signed integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt32(littleEndian?: boolean): number { + const value = this.getInt32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a signed integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setInt32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets an unsigned integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint32(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint32(littleEndian?: boolean): number { + const value = this.getUint32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets an unsigned integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setUint32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a float. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat32(byteOffset, littleEndian) + } + + /** + * Reads the next float. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat32(littleEndian?: boolean): number { + const value = this.getFloat32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a float. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat32(byteOffset, value, littleEndian) + } + + /** + * Writes the next float. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setFloat32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a double. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat64(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat64(byteOffset, littleEndian) + } + + /** + * Reads the next double. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat64(littleEndian?: boolean): number { + const value = this.getFloat64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a double. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat64(byteOffset, value, littleEndian) + } + + /** + * Writes the next double. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setFloat64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigInt64(byteOffset, littleEndian) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigInt64(littleEndian?: boolean): bigint { + const value = this.getBigInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigInt64(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigInt64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigUint64(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigUint64(littleEndian?: boolean): bigint { + const value = this.getBigUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigUint64(byteOffset, value, littleEndian) + } + + /** + * Writes the next unsigned long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigUint64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigInt64(byteOffset, littleEndian)) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt64(littleEndian?: boolean): number { + const value = this.getInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigInt64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigUint64(byteOffset, littleEndian)) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint64(littleEndian?: boolean): number { + const value = this.getUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigUint64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { + return new Uint8Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned bytes. + * @param byteLength The byte length. + * @returns The value. + */ + readUint8Array(byteLength?: number): Uint8Array { + const value = this.getUint8Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8Array(byteOffset: number, value: Uint8Array): void { + const byteLength = value.byteLength + this.getUint8Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint8Array(value: Uint8Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint8Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets an array of unsigned shorts. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { + if (byteLength !== undefined) { + byteLength = Math.floor(byteLength / 2) + } + return new Uint16Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned shorts. + * @param byteLength The byte length. + * @returns The value. + */ + readUint16Array(byteLength?: number): Uint16Array { + const value = this.getUint16Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint16Array(byteOffset: number, value: Uint16Array): void { + const byteLength = value.byteLength + this.getUint16Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint16Array(value: Uint16Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint16Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets a string. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { + const decoder = new util.TextDecoder(byteEncoding || "utf-8") + const encoded = this.getUint8Array(byteOffset, byteLength) + return decoder.decode(encoded) + } + + /** + * Reads the next string. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + readString(byteLength?: number, byteEncoding?: string): string { + const value = this.getString(this.mByteOffset, byteLength, byteEncoding) + if (byteLength === undefined) { + this.mByteOffset = this.dataView.byteLength + } else { + this.mByteOffset += byteLength + } + return value + } + + /** + * Sets a string. + * @param byteOffset The byte offset. + * @param value The string. + * @param byteEncoding The byte encoding. + * @returns The byte length. + */ + setString(byteOffset: number, value: string, byteEncoding?: string, write?: boolean): number { + if (byteEncoding && byteEncoding !== "utf-8") { + throw new TypeError("String encoding '" + byteEncoding + "' is not supported") + } + const encoder = new util.TextEncoder() + const byteLength = Math.min(this.dataView.byteLength - byteOffset, value.length * 4) + if (write) { + this.checkWriteCapacity(byteLength) + } + const destination = this.getUint8Array(byteOffset, byteLength) + const written = encoder.encodeInto(value, destination).written + return written || 0 + } + + /** + * Writes the next a string. + * @param value The string. + * @param byteEncoding The byte encoding. + */ + writeString(value: string, byteEncoding?: string): void { + const byteLength = this.setString(this.mByteOffset, value, byteEncoding, true) + this.mByteOffset += byteLength + } + + /** + * Formats to a string. + * @param format The string format. + * @returns The string. + */ + toString(format?: string): string { + return [...this.getUint8Array(0)].map((byte: number) => { + switch(format) { + case "hex": + return ("00" + byte.toString(16)).slice(-2) + default: + return byte.toString(10) + } + }).join(" ") + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets new file mode 100644 index 0000000000000000000000000000000000000000..437b52f18049b9ba77e47350033482a06368c5c4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HiLog from '@ohos.hilog'; + +const DOMAIN: number = 0x00FF; +const TAG = "Flutter"; +const SYMBOL = " --> "; +// const FILTER_KEYS = [ +// new RegExp('hide', "gi") +// ] + +// export function filterKey(target: any, propKey: string, descriptor: PropertyDescriptor) { +// const original = descriptor.value; +// descriptor.value = function (...args: string[]) { +// let filterResult = args.map((str) => { +// let tempStr = str +// FILTER_KEYS.forEach((filterKey) => tempStr = tempStr.replace(filterKey, "**")) +// return tempStr +// }); +// const result = original.call(this, ...filterResult); +// return result; +// }; +// } + +/** + * Basic log class + */ +export default class Log { + /** + * Outputs debug-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static d(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.DEBUG)) { + HiLog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs info-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static i(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.INFO)) { + HiLog.info(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs warning-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static w(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.WARN)) { + HiLog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs error-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static e(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.ERROR)) { + HiLog.error(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs fatal-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static f(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.FATAL)) { + HiLog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Checks whether logs of the specified tag, and level can be printed. + * + * @param tag Identifies the log tag. + * @param level log level + * @since 7 + */ + private static isLoggable(level: HiLog.LogLevel): boolean { + return HiLog.isLoggable(DOMAIN, TAG, level); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..1899f74069a24a3e250378b11ac1c9492f03b8f3 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../plugin/common/BinaryMessenger'; +import StringUtils from './StringUtils'; + +export default class MessageChannelUtils { + static resizeChannelBuffer(messenger: BinaryMessenger, channel: string, newSize: number) { + const dataStr = `resize\r${channel}\r${newSize}` + messenger.send(BasicMessageChannel.CHANNEL_BUFFERS_CHANNEL, StringUtils.stringToArrayBuffer(dataStr)); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..691ea0f360b40adb266bde566c2f66292a2aa0ff --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import common from '@ohos.app.ability.common'; +import fs from '@ohos.file.fs'; +import Log from './Log'; + +/** + * ohos路径获取工具 + */ +const TAG: string = "PathUtils"; + +export default class PathUtils { + static getFilesDir(context: common.Context): string { + return context.filesDir; + } + + static getCacheDirectory(context: common.Context): string { + return context.cacheDir; + } + + static getDataDirectory(context: common.Context): string { + const name = "flutter"; + const flutterDir = context.filesDir + "/" + name; + if (!fs.accessSync(flutterDir)) { + try { + fs.mkdirSync(flutterDir); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + return null; + } + } + return flutterDir; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeb7c554c30b5d3625851afc214dda8d31da9917 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * 默认字符串工具 + */ +export default class StringUtils { + static stringToArrayBuffer(str: string): ArrayBuffer { + let textEncoder = new util.TextEncoder("utf-8"); + return textEncoder.encodeInto(str).buffer; + } + + static arrayBufferToString(buffer: ArrayBuffer): string { + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true }) + return textDecoder.decode(new Uint8Array(buffer)) + } + + static isNotEmpty(str: string): boolean { + return str && str.length > 0; + } + + static isEmpty(str: string): boolean { + return (!str) || str.length == 0; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3879f4a40ea307f7491a4808ad3b816cc98b13e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class ToolUtils { + static isObj(object: Object): boolean { + return object && typeof (object) == 'object'; + } + + static implementsInterface(obj: ESObject, method: string): boolean { + return Reflect.has(obj, method) && typeof obj[method] === 'function' + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets new file mode 100644 index 0000000000000000000000000000000000000000..3caaadea7aa0cb84be3542be9c4595139cd25af4 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hiTraceMeter from '@ohos.hiTraceMeter' + +export class TraceSection { + + static taskId: number = 1; + + private static cropSectionName(sectionName: string): string { + return sectionName.length < 124 ? sectionName : sectionName.substring(0, 124) + "..."; + } + + /** + * Wraps Trace.beginSection to ensure that the line length stays below 127 code units. + * + * @param sectionName The string to display as the section name in the trace. + */ + public static begin(sectionName: string): void { + hiTraceMeter.startTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId++); + } + + /** Wraps Trace.endSection. */ + public static end(sectionName: string): void { + hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e08f41fe9171658365b4e2c806b075807ddc423 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class AccessibilityBridge { + constructor(){ + + } +} + +export enum Action { + TAP = 1 << 0, + LONG_PRESS = 1 << 1, + SCROLL_LEFT = 1 << 2, + SCROLL_RIGHT = 1 << 3, + SCROLL_UP = 1 << 4, + SCROLL_DOWN = 1 << 5, + INCREASE = 1 << 6, + DECREASE = 1 << 7, + SHOW_ON_SCREEN = 1 << 8, + MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 << 9, + MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 << 10, + SET_SELECTION = 1 << 11, + COPY = 1 << 12, + CUT = 1 << 13, + PASTE = 1 << 14, + DID_GAIN_ACCESSIBILITY_FOCUS = 1 << 15, + DID_LOSE_ACCESSIBILITY_FOCUS = 1 << 16, + CUSTOM_ACTION = 1 << 17, + DISMISS = 1 << 18, + MOVE_CURSOR_FORWARD_BY_WORD = 1 << 19, + MOVE_CURSOR_BACKWARD_BY_WORD = 1 << 20, + SET_NEXT = 1 << 21, +}; \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets new file mode 100644 index 0000000000000000000000000000000000000000..f95a9c04a7a44a99505b9882ba1291e7bfcb1604 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import matrix4 from '@ohos.matrix4'; + +/** + * Dynamic View creation + * from a recursive data structure + * + * exported @Component: DynamicView + * exported view model classes: + * - DVModelContainer + * - DVModel + * - DVModelParameters + * - DVModelEvents + * - DVModelChildren + * + * The purpose of exporting the DVModel classes + * is to make them available to the converter from + * JD's XML format and the expression parser. These + * components are expected to generate and update the + * DVModel. + * + * An application written by JS should only import + * DynamicView, DVModelContainer to be used in their own ArkUI + * container view. + */ + +/** + * View Model classes + */ + +@Observed +export class DVModelParameters extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelEvents extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelChildren extends Array { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +let nextId: number = 1; + +@Observed +export class DVModel { + id_: number; + compType: string; + params: DVModelParameters; + events: DVModelEvents; + children: DVModelChildren; + builder: ESObject; + + constructor(compType: string, params: DVModelParameters, events: DVModelEvents, children: DVModelChildren, builder?: ESObject) { + this.id_ = nextId++; + this.compType = compType; + this.params = params ?? new DVModelParameters; + this.events = events; + this.children = children; + this.builder = builder; + } + + public getLayoutParams(): DVModelParameters { + return this.params; + } +} + +// includes the root DVModel objects. +export class DVModelContainer { + model: DVModel; + + constructor(model: DVModel) { + this.model = model; + } +} + +/** + DynamicView is the @Component that does all the work: + + The following 4 features are the key solution elements for dynamic View + construction and update: + + 1. The if statement decides which framework component to create. + We can not use a factory function here, because that would requite calling + a regular function inside build() or a @Builder function. + + 2. Take note of the @Builder for Row, Column containers: + These functions create DynamicView Views inside a DynamicView + view. This behaviour is why we talk about DynamicView as a 'recursive' View. + All @Builder functions are member functions of the DynamicView @Component to + retain access ('this.xyz') to its decorated state variables. + + 3. The @Extend functions execute attribute and event handler registration functions + for all attributes and events permissable on the framework component, irrespective + if DVModelParameters or DVModelEvents objects includes a value or not. If not + the attribute or event is set to 'undefined' by intention. This is required to unset + any previously set value. + + 4. The scope ('this') of any lambda registered as an event hander function, e.g. for onClick, + is the @Component, in which the DVModel object is initialized. This said, it is advised to initialize + the DVModel object in the @Component that is parent to outmost DynamicView. Thereby, + any event handler function is able to mutate decorated state variables of that @Component + + */ + +@Component +export struct DynamicView { + @ObjectLink model: DVModel; + @ObjectLink children: DVModelChildren; + @ObjectLink params: DVModelParameters; + @ObjectLink events: DVModelEvents; + @BuilderParam customBuilder?: ($$: BuilderParams) => void; + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + getEvents: (events: DVModelEvents, element: string) => ESObject = (events: DVModelEvents, element: string): ESObject => { + let events2 = events as Record; + return events2.element; + } + + /* + we use this @Styles member function to set all common attributes and event handlers + and set component specific attribute and event handler functions in the @Builder function + */ + @Styles + common_attrs() { + // let params2 = this.params as Record | matrix4.Matrix4Transit>; + // .width(this.params["width"]) + // .height(this.params["height"]) + // .backgroundColor(this.params["backgroundColor"]) + // .onClick(this.events["onClick"]) + // .margin({ + // left: this.params["marginLeft"], + // right: this.params["marginRight"], + // top: this.params["marginTop"], + // bottom: this.params["marginBottom"] + // }) + // .onTouch(this.events["onTouch"]) + // .onFocus(this.events['onFocus']) + // .onBlur(this.events["onBlur"]) + // .translate({ + // x: this.params["translateX"], + // y: this.params["translateY"], + // z: this.params["translateZ"] + // }) + // .transform(this.params["matrix"]) + // .direction(this.params["direction"])this.getParams(this.params, "") + .width(this.getParams(this.params, "width")) + .height(this.getParams(this.params, "height")) + .backgroundColor(this.getParams(this.params, "backgroundColor")) + .onClick(this.getEvents(this.events, "onClick")) + .margin({ + left: this.getParams(this.params, "marginLeft"), + right: this.getParams(this.params, "marginRight"), + top: this.getParams(this.params, "marginTop"), + bottom: this.getParams(this.params, "marginBottom") + }) + .onTouch(this.getEvents(this.events, "onTouch")) + .onFocus(this.getEvents(this.events, "onFocus")) + .onBlur(this.getEvents(this.events, "onBlur")) + .translate({ + x: this.getParams(this.params, "translateX"), + y: this.getParams(this.params, "translateY"), + z: this.getParams(this.params, "translateZ") + }) + .transform(this.getParams(this.params, "matrix")) + .direction(this.getParams(this.params, "direction")) + } + + @Styles + clip_attrs() { + .clip(this.getParams(this.params, "rectWidth") ? new Rect({ + width: this.getParams(this.params, "rectWidth"), + height: this.getParams(this.params, "rectHeight"), + radius: this.getParams(this.params, "rectRadius") + }) : null) + .clip(this.getParams(this.params, "pathWidth") ? new Path({ + width: this.getParams(this.params, "pathWidth"), + height: this.getParams(this.params, "pathHeight"), + commands: this.getParams(this.params, "pathCommands") + }) : null) + } + + @Builder + buildChildren() { + ForEach(this.children, + (child: ESObject) => { + DynamicView({ + model: child as DVModel, + params: child.params, + events: child.events, + children: child.children, + customBuilder: child.builder + }) + }, + (child: ESObject) => `${child.id_}` + ) + } + + @Builder + buildRow() { + Row() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildColumn() { + Column() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildStack() { + Stack() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + .alignContent(this.getParams(this.params, "alignContent")) + } + + @Builder + buildText() { + Text(`${this.getParams(this.params, "value")}`) + .common_attrs() + .fontColor(this.getParams(this.params, "fontColor")) + } + + @Builder + buildImage() { + Image(this.getParams(this.params, "src")) + .common_attrs() + } + + // Button with label + @Builder + buildButton() { + Button(this.getParams(this.params, "value")) + .common_attrs() + } + + @Builder + buildCustom() { + if (this.customBuilder) { + this.customBuilder(new BuilderParams(this.params)); + } + } + + build() { + if (this.model.compType == "Column") { + this.buildColumn() + } else if (this.model.compType == "Row") { + this.buildRow() + } else if (this.model.compType == "Stack") { + this.buildStack() + } else if (this.model.compType == "Text") { + this.buildText() + } else if (this.model.compType == "Image") { + this.buildImage() + } else if (this.model.compType == "Button") { + this.buildButton() + } else { + this.buildCustom() + } + } +} + +export class BuilderParams { + params: DVModelParameters; + + constructor(params: DVModelParameters) { + this.params = params; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b97e5e5092748f7bc9e0f3af7482921891baf0f --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DVModel, DVModelParameters, DVModelEvents, DVModelChildren } from "./dynamicView"; + +export function createDVModelFromJson(json: Object): DVModel { + + /* private use helper functions */ + let createChildrenFrom: (children: Array) => DVModelChildren = (children: Array): DVModelChildren => { + let result = new DVModelChildren(); + if (Array.isArray(children)) { + (children as Array).forEach(child => { + const childView = createDVModelFromJson(child); + if (childView != undefined) { + result.push(childView); + } + }); + } + return result; + } + + let setParams: (result: DVModelParameters | DVModelEvents, key: ESObject, element: Object ) => void = (result: DVModelParameters, key: ESObject, element: ESObject): void => { + let newResult = result as Record; + newResult.key = element.key; + } + + let createAttributesFrom: (attributes: Object) => DVModelParameters = (attributes: Object): DVModelParameters => { + let result = new DVModelParameters(); + if ((typeof attributes == "object") && (!Array.isArray(attributes))) { + Object.keys(attributes).forEach(k => {setParams(result, k, attributes)}); + } + return result; + } + + let createEventsFrom: (events: Object) => DVModelEvents = (events: Object): DVModelEvents => { + let result = new DVModelEvents(); + if ((typeof events == "object") && (!Array.isArray(events))) { + Object.keys(events).forEach(k => {setParams(result, k, events)}); + } + return result; + } + + if (typeof json !== 'object') { + console.error("createDVModelFromJson: input is not JSON"); + return undefined; + } + + let jsonObject = json as Record; + return new DVModel( + jsonObject.compType, + createAttributesFrom(jsonObject["attributes"]), + createEventsFrom(jsonObject["events"]), + createChildrenFrom(jsonObject["children"]), + jsonObject["build"] + ); +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..f52152001a497e70586215af090b2a81190e1187 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from '../embedding/engine/FlutterNapi'; + +export class FlutterCallbackInformation { + callbackName: string; + callbackClassName: string; + callbackLibraryPath: string; + + /** + * Get callback information for a given handle. + * + * @param handle the handle for the callback, generated by `PluginUtilities.getCallbackHandle` in + * `dart:ui`. + * @return an instance of FlutterCallbackInformation for the provided handle. + */ + static lookupCallbackInformation(handle: number): FlutterCallbackInformation { + return FlutterNapi.nativeLookupCallbackInformation(handle); + } + + constructor(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { + this.callbackName = callbackName; + this.callbackClassName = callbackClassName; + this.callbackLibraryPath = callbackLibraryPath; + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets new file mode 100644 index 0000000000000000000000000000000000000000..9138ad728502e49e675e69e1fd533d80ad7016bc --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import DartExecutor from '../embedding/engine/dart/DartExecutor'; +import { EngineLifecycleListener } from '../embedding/engine/FlutterEngine'; +import FlutterNapi from '../embedding/engine/FlutterNapi'; +import Log from '../util/Log'; +import FlutterPluginRegistry from '../app/FlutterPluginRegistry'; +import FlutterRunArguments from './FlutterRunArguments'; +import { FlutterView } from './FlutterView'; + +const TAG: string = "FlutterNativeView"; + +export default class FlutterNativeView { + private mContext: common.Context; + private mPluginRegistry: FlutterPluginRegistry; + private mFlutterNapi: FlutterNapi; + private dartExecutor: DartExecutor; + private mFlutterView: FlutterView; + private applicationIsRunning: boolean; + + constructor(context: common.Context, isBackgroundView?: boolean) { + if (isBackgroundView) { + Log.i(TAG, "isBackgroundView is no longer supported and will be ignored"); + } + this.mContext = context; + this.mPluginRegistry = new FlutterPluginRegistry(); + this.mFlutterNapi = new FlutterNapi(); + //this.mFlutterNapi.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.dartExecutor = new DartExecutor(this.mFlutterNapi, this.mContext.resourceManager); + this.mFlutterNapi.addEngineLifecycleListener(new EngineLifecycleListenerImpl(this.mFlutterView, this.mPluginRegistry)); + this.attach(this.mFlutterNapi, this.dartExecutor); + this.assertAttached(this.mFlutterNapi); + } + + attach(flutterNapi: FlutterNapi, dartExecutor: DartExecutor): void { + flutterNapi.attachToNative(); + dartExecutor.onAttachedToNAPI(); + } + + assertAttached(flutterNapi: FlutterNapi): void { + if (!this.isAttached(flutterNapi)) { + throw new Error('Platform View is not attached'); + } + } + + isAttached(flutterNapi: FlutterNapi): boolean { + return flutterNapi.isAttached(); + } + + detachFromFlutterView(): void { + this.mPluginRegistry.detach(); + this.mFlutterView = null; + } + + destroy(): void { + this.mPluginRegistry.destroy(); + this.dartExecutor.onDetachedFromNAPI(); + this.mFlutterView = null; + //this.mFlutterNapi.removeIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.applicationIsRunning = false; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor; + } + + getPluginRegistry(): FlutterPluginRegistry { + return this.mPluginRegistry; + } + + attachViewAndAbility(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mPluginRegistry.attach(flutterView, context); + } + + runFromBundle(args: FlutterRunArguments): void { + if (args.entrypoint == null) { + throw new Error("an entrypoint must be specific"); + } + this.assertAttached(this.mFlutterNapi); + if (this.applicationIsRunning) { + throw new Error("this flutter engine instance is already running an application"); + } + this.mFlutterNapi.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.resourceManager, null); + this.applicationIsRunning = true; + } + + isApplicationRunning(): boolean { + return this.applicationIsRunning; + } + + // getObservatoryUri(): string { + // return this.mFlutterNapi.getObservatoryUri(); + // } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private flutterView: FlutterView; + private pluginRegistry: FlutterPluginRegistry; + + onPreEngineRestart(): void { + if (this.flutterView != null) { + //this.flutterView.resetAccessibilityTree(); + } + + if (this.pluginRegistry == null) { + return; + } + + this.pluginRegistry.onPreEngineRestart(); + } + + onEngineWillDestroy(): void { + + } + + constructor(flutterView: FlutterView, pluginRegistry: FlutterPluginRegistry) { + this.flutterView = flutterView; + this.pluginRegistry = pluginRegistry; + } +} + + diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets new file mode 100644 index 0000000000000000000000000000000000000000..d17ec28d1fdc6237ee486362751ee25e58590887 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterRunArguments { + public bundlePath: string; + public entrypoint: string; + public libraryPath: string; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf38a74159eb41c2ca4b6ede7f9e04e0cc66bf5a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterView { + +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f100263589238f2d354ccf92636ab46fb03d040 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +export interface TextureRegistry { + + createSurfaceTexture(): SurfaceTextureEntry; + registerSurfaceTexture(): SurfaceTextureEntry; + + onTrimMemory(level: number) : void; +} + +interface SurfaceTextureEntry { + id(): number; + + release(): void; +} + +interface OnFrameConsumedListener { + onFrameConsumed(): void; +} + +interface OnTrimMemoryListener { + onTrimMemory(level: number) : void; +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..14c854f518a6a4f98ef7ece63da2e957ab98f69e --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "net.openvalley.helloworld", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "flutter_embedding", + "type": "har", + "deviceTypes": [ + "default" + ] + } +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..2e1da5f963e44f4e654fbfab9d939c6250b20f14 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,264 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getApplicationCachePath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationCachePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationCachePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..d43b8c9e4c7dae7329e5baf250c4d9687fbe612b --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getApplicationCachePath(): string { + return this.context.cacheDir; + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4893b7589216e710fa412c5bc38dd5632f45aad7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..0db841ed9cff9fdea904b802e68d01f1d9b2b36a --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3517276bcfc5453175c8f9b532d32b71e7d0e76 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/lib/path_provider_ohos/pubspec.yaml b/ohos/test_cached_network_image/lib/path_provider_ohos/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..f05fd18b993f0c0376d58244b6670c669f94c306 --- /dev/null +++ b/ohos/test_cached_network_image/lib/path_provider_ohos/pubspec.yaml @@ -0,0 +1,51 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +name: path_provider_ohos +description: Ohos implementation of the path_provider plugin. +repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_ohos +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 +version: 1.0.0 +publish_to: none + +environment: + sdk: ">=2.18.0 <4.0.0" + flutter: ">=3.3.0" + +flutter: + plugin: + implements: path_provider + platforms: + ohos: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + dartPluginClass: PathProviderOhos + linux: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + dartPluginClass: PathProviderOhos + +dependencies: + flutter: + sdk: flutter + path_provider_platform_interface: ^2.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + pigeon: ^9.2.4 + test: ^1.16.0 diff --git a/ohos/test_cached_network_image/lib/src/fake_cache_manager.dart b/ohos/test_cached_network_image/lib/src/fake_cache_manager.dart new file mode 100644 index 0000000000000000000000000000000000000000..887b6cc5102239875a41e2c2c6c66da41327aa8a --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/fake_cache_manager.dart @@ -0,0 +1,151 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:typed_data'; + +import 'package:file/memory.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:mocktail/mocktail.dart'; +import 'dart:async'; + +class FakeCacheManager extends Mock implements CacheManager { + void throwsNotFound(String url) { + when(() => + getFileStream( + url, + key: any(named: 'key'), + headers: any(named: 'headers'), + withProgress: any(named: 'withProgress'), + )) + .thenThrow(HttpExceptionWithStatus(404, 'Invalid statusCode: 404', + uri: Uri.parse(url))); + } + + ExpectedData returns(String url, + List imageData, { + Duration? delayBetweenChunks, + }) { + const chunkSize = 8; + final chunks = [ + for (int offset = 0; offset < imageData.length; offset += chunkSize) + Uint8List.fromList(imageData.skip(offset).take(chunkSize).toList()), + ]; + + when(() => + getFileStream( + url, + key: any(named: 'key'), + headers: any(named: 'headers'), + withProgress: any(named: 'withProgress'), + )).thenAnswer((_) => + _createResultStream( + url, + chunks, + imageData, + delayBetweenChunks, + )); + + return ExpectedData( + chunks: chunks.length, + totalSize: imageData.length, + chunkSize: chunkSize, + ); + } + + Stream _createResultStream(String url, + List chunks, + List imageData, + Duration? delayBetweenChunks,) async* { + var totalSize = imageData.length; + var downloaded = 0; + for (var chunk in chunks) { + downloaded += chunk.length; + if (delayBetweenChunks != null) { + await Future.delayed(delayBetweenChunks); + } + yield DownloadProgress(url, totalSize, downloaded); + } + var file = MemoryFileSystem().systemTempDirectory.childFile('test.jpg'); + await file.writeAsBytes(imageData); + yield FileInfo(file, FileSource.Online, + DateTime.now().add(const Duration(days: 1)), url); + } +} + +class FakeImageCacheManager extends Mock implements ImageCacheManager { + ExpectedData returns(String url, + List imageData, { + Duration? delayBetweenChunks, + }) { + const chunkSize = 8; + final chunks = [ + for (int offset = 0; offset < imageData.length; offset += chunkSize) + Uint8List.fromList(imageData.skip(offset).take(chunkSize).toList()), + ]; + + when(() => + getImageFile( + url, + key: any(named: 'key'), + headers: any(named: 'headers'), + withProgress: any(named: 'withProgress'), + maxHeight: any(named: 'maxHeight'), + maxWidth: any(named: 'maxWidth'), + )).thenAnswer((_) => + _createResultStream( + url, + chunks, + imageData, + delayBetweenChunks, + )); + + return ExpectedData( + chunks: chunks.length, + totalSize: imageData.length, + chunkSize: chunkSize, + ); + } + + Stream _createResultStream(String url, + List chunks, + List imageData, + Duration? delayBetweenChunks,) async* { + var totalSize = imageData.length; + var downloaded = 0; + for (var chunk in chunks) { + downloaded += chunk.length; + if (delayBetweenChunks != null) { + await Future.delayed(delayBetweenChunks); + } + yield DownloadProgress(url, totalSize, downloaded); + } + var file = MemoryFileSystem().systemTempDirectory.childFile('test.jpg'); + await file.writeAsBytes(imageData); + yield FileInfo(file, FileSource.Online, + DateTime.now().add(const Duration(days: 1)), url); + } +} + +class ExpectedData { + final int chunks; + final int totalSize; + final int chunkSize; + + const ExpectedData({ + required this.chunks, + required this.totalSize, + required this.chunkSize, + }); +} diff --git a/ohos/test_cached_network_image/lib/src/fix_bug.dart b/ohos/test_cached_network_image/lib/src/fix_bug.dart new file mode 100644 index 0000000000000000000000000000000000000000..136989a07ea851c363fec3cdafdea51bcb4ae8c7 --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/fix_bug.dart @@ -0,0 +1,246 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'dart:convert'; +import 'dart:typed_data'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:dio/dio.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:convert/convert.dart'; + +class FixBug extends StatefulWidget { + @override + State createState() => FixBugState(); +} + +class FixBugState extends State { + final defaultCacheManager = DefaultCacheManager(); + + Stream? fileStream; + + final String url = 'http://via.placeholder.com/350x150'; + + bool lock = false; + bool apiLock = false; + + String statusCode = ''; + String dioGet = ''; + String path = ''; + String cachePath = ''; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('仅测试使用'), + ), + body: ListView( + children: [ + Text('图片地址: $url'), + fenGe(), + Text('CachedNetworkImageProvider实现, 没显示就是有问题'), + Image( + image: CachedNetworkImageProvider( + 'http://via.placeholder.com/350x150', + ), + ), + fenGe(), + Text('Image.network实现, 证明网络没有问题'), + Image.network(url), + fenGe(), + // TextButton(onPressed: () async => await DefaultCacheManager().emptyCache(), child: const Text('清除缓存')), + // TextButton(onPressed: () async => await api(), child: const Text('使用flutter_cache_manager获取图片')), + // Visibility( + // visible: apiLock, + // child: const Text( + // '当前正在进行网络请求', + // style: TextStyle(color: Colors.red), + // )), + // Visibility( + // visible: !apiLock, + // child: Column( + // children: [ + // Text('这里显示获取到的状态码: $statusCode'), + // Text('这里显示获取到的网络信息: $dioGet'), + // ], + // )), + // fenGe(), + // 证明path没有问题 + Row( + mainAxisAlignment: MainAxisAlignment.spaceAround, + children: [ + FilledButton( + onPressed: () async { + defaultCacheManager.emptyCache(); + }, + child: const Text('清除缓存')), + FilledButton( + onPressed: () async { + final dio = Dio(); + final Response response = await dio.get( + url, + options: Options( + responseType: ResponseType.bytes, // 设置响应类型为字节数组 + ), + ); + + await defaultCacheManager.putFile(url, response.data as Uint8List); + final data = await defaultCacheManager.getFileFromCache(url); + setState(() { + cachePath = data?.file.path ?? ''; + }); + }, + child: const Text('重新获取信息')), + ], + ), + TextButton( + onPressed: () async { + final data = await defaultCacheManager.getFileFromCache(url); + setState(() { + cachePath = data?.file.path ?? '无'; + }); + }, + child: const Text('单独测试缓存路径, 有东西则path正常')), + Visibility(visible: cachePath.isNotEmpty, child: Text(cachePath)), + fenGe(), + TextButton( + onPressed: () async { + defaultCacheManager.emptyCache(); + }, + child: const Text('清除缓存')), + Visibility(visible: path.isNotEmpty, child: Text(path)), + TextButton(onPressed: () async => await cacheManager(), child: const Text('使用flutter_cache_manager获取图片')), + Visibility( + visible: lock, + child: const Text( + '当前正在进行网络请求', + style: TextStyle(color: Colors.red), + )), + Visibility( + visible: !lock && fileStream != null, + child: StreamBuilder( + stream: fileStream, + builder: (context, snapshot) { + Widget body; + final loading = !snapshot.hasData || snapshot.data is DownloadProgress; + + if (snapshot.hasError) { + body = ListTile( + title: const Text('出现错误'), + subtitle: Text(snapshot.error.toString()), + ); + } else if (loading) { + body = ListTile( + title: const Text('加载中'), + ); + } else { + final FileInfo fileInfo; + fileInfo = snapshot.requireData as FileInfo; + fileStream = null; + body = Column( + children: [ + Container( + height: 200, + margin: EdgeInsets.only(top: 20, bottom: 20), + child: Image.file(fileInfo.file), + ), + ListTile( + title: const Text('远程链接'), + subtitle: Text(fileInfo.originalUrl), + ), + ListTile( + title: const Text('本地文件路径'), + subtitle: Text(fileInfo.file.path), + ), + ListTile( + title: const Text('加载来源'), + subtitle: Text(fileInfo.source.toString()), + ), + ListTile( + title: const Text('有效期至'), + subtitle: Text(fileInfo.validTill.toIso8601String()), + ), + ], + ); + } + return body; + }, + )) + ], + ), + ); + } + + Widget fenGe() { + return Container( + width: MediaQuery.of(context).size.width * 0.9, + height: 1, + decoration: BoxDecoration(color: Colors.grey), + ); + } + + Future cacheManager() async { + if (lock == true) { + return; + } + setState(() { + lock = true; + }); + fileStream = defaultCacheManager.getFileStream(url, withProgress: true); + setState(() { + lock = false; + }); + } + + Future api() async { + if (apiLock == true) { + return; + } + setState(() { + apiLock = true; + statusCode = ''; + dioGet = ''; + }); + try { + final dio = Dio(); + final Response response = await dio.get( + url, + options: Options( + responseType: ResponseType.bytes, // 设置响应类型为字节数组 + ), + ); + print('请求的状态码: ${response.statusCode}'); + + print('ohFlutter: 这里是dio获取到的网络信息${response.data}'); + setState(() { + statusCode = response.statusCode.toString(); + dioGet = response.data.toString(); + }); + } catch (e) { + setState(() { + dioGet = e.toString(); + }); + } finally { + setState(() { + apiLock = false; + }); + } + } + + /// 获取图片信息 + Future getImage() async {} +} diff --git a/ohos/test_cached_network_image/lib/src/image_cache_manager_test.dart b/ohos/test_cached_network_image/lib/src/image_cache_manager_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..0d29c641e2848063a50a4abd17b54380c593b6ee --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/image_cache_manager_test.dart @@ -0,0 +1,121 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'dart:async'; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:mocktail/mocktail.dart'; + +import '../common/test_page.dart'; +import 'fake_cache_manager.dart'; +import 'image_data.dart'; + +class ImageCacheManagerTestPage extends TestPage { + ImageCacheManagerTestPage(String title, {Key? key}) : super(title: title, key: key) { + PaintingBinding.instance.imageCache.clear(); + PaintingBinding.instance.imageCache.clearLiveImages(); + + test('提供ImageCacheManager应调用getImageFile', () async { + var url = 'foo.nl'; + + var cacheManager = FakeImageCacheManager(); + cacheManager.returns(url, kTransparentImage); + final imageAvailable = Completer(); + + final ImageProvider imageProvider = CachedNetworkImageProvider(url, cacheManager: cacheManager); + final result = imageProvider.resolve(ImageConfiguration.empty); + + result.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) { + imageAvailable.complete(); + }, + )); + await imageAvailable.future; + + cacheManager.getImageFile( + url, + key: 'key', + headers: {'headers': ''}, + withProgress: false, + ); + }); + + test('提供CacheManager时应调用getFileStream', () async { + var url = 'foo.nl'; + + var cacheManager = FakeCacheManager(); + cacheManager.returns(url, kTransparentImage); + final imageAvailable = Completer(); + + final ImageProvider imageProvider = CachedNetworkImageProvider(url, cacheManager: cacheManager); + final result = imageProvider.resolve(ImageConfiguration.empty); + + result.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) { + imageAvailable.complete(); + }, + )); + await imageAvailable.future; + + cacheManager.getFileStream( + url, + key: 'key', + headers: {'headers': ''}, + withProgress: false, + ); + }); + + test('为CacheManager提供maxHeight throws断言', () async { + var url = 'foo.nl'; + final caughtError = Completer(); + + var cacheManager = FakeCacheManager(); + cacheManager.returns(url, kTransparentImage); + final imageAvailable = Completer(); + + final ImageProvider imageProvider = CachedNetworkImageProvider(url, cacheManager: cacheManager, maxHeight: 20); + final result = imageProvider.resolve(ImageConfiguration.empty); + + result.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) { + imageAvailable.complete(); + }, onError: (dynamic error, StackTrace? stackTrace) { + caughtError.complete(error); + })); + final dynamic err = await caughtError.future; + + err; + }); + + test('为CacheManager提供maxWidth throws断言', () async { + var url = 'foo.nl'; + final caughtError = Completer(); + + var cacheManager = FakeCacheManager(); + cacheManager.returns(url, kTransparentImage); + final imageAvailable = Completer(); + + final ImageProvider imageProvider = CachedNetworkImageProvider(url, cacheManager: cacheManager, maxWidth: 20); + final result = imageProvider.resolve(ImageConfiguration.empty); + + result.addListener(ImageStreamListener((ImageInfo image, bool synchronousCall) { + imageAvailable.complete(); + }, onError: (dynamic error, StackTrace? stackTrace) { + caughtError.complete(error); + })); + final dynamic err = await caughtError.future; + err; + }); + } +} diff --git a/ohos/test_cached_network_image/lib/src/image_data.dart b/ohos/test_cached_network_image/lib/src/image_data.dart new file mode 100644 index 0000000000000000000000000000000000000000..33caf8e388bdbaa2aab3a637f4b045e3dbe6320c --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/image_data.dart @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +const List kTransparentImage = [ + 0x89, + 0x50, + 0x4E, + 0x47, + 0x0D, + 0x0A, + 0x1A, + 0x0A, + 0x00, + 0x00, + 0x00, + 0x0D, + 0x49, + 0x48, + 0x44, + 0x52, + 0x00, + 0x00, + 0x00, + 0x01, + 0x00, + 0x00, + 0x00, + 0x01, + 0x08, + 0x06, + 0x00, + 0x00, + 0x00, + 0x1F, + 0x15, + 0xC4, + 0x89, + 0x00, + 0x00, + 0x00, + 0x0A, + 0x49, + 0x44, + 0x41, + 0x54, + 0x78, + 0x9C, + 0x63, + 0x00, + 0x01, + 0x00, + 0x00, + 0x05, + 0x00, + 0x01, + 0x0D, + 0x0A, + 0x2D, + 0xB4, + 0x00, + 0x00, + 0x00, + 0x00, + 0x49, + 0x45, + 0x4E, + 0x44, + 0xAE, +]; diff --git a/ohos/test_cached_network_image/lib/src/image_provider_test.dart b/ohos/test_cached_network_image/lib/src/image_provider_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..13c8610b411a28e68ce043f3bf5a738268f17279 --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/image_provider_test.dart @@ -0,0 +1,145 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:math' as math; +import 'dart:ui' show Codec, FrameInfo; + +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; +import 'fake_cache_manager.dart'; +import 'image_data.dart'; + +class ImageProviderTestPage extends TestPage { + ImageProviderTestPage(String title, {Key? key}) + : super(title: title, key: key) { + FakeCacheManager cacheManager = FakeCacheManager(); + + PaintingBinding.instance.imageCache.clear(); + PaintingBinding.instance.imageCache.clearLiveImages(); + + test('预期会引发带有statusCode的异常-从缓存中逐出', () async { + const requestUrl = 'foo-url'; + cacheManager.throwsNotFound(requestUrl); + + final caughtError = Completer(); + + final ImageProvider imageProvider = + CachedNetworkImageProvider(requestUrl, cacheManager: cacheManager); + expect(imageCache.pendingImageCount, 0); + expect(imageCache.statusForKey(imageProvider).untracked, true); + + final result = imageProvider.resolve(ImageConfiguration.empty); + + expect(imageCache.pendingImageCount, 1); + expect(imageCache.statusForKey(imageProvider).pending, true); + + result.addListener(ImageStreamListener((ImageInfo info, bool syncCall) {}, + onError: (dynamic error, StackTrace? stackTrace) { + caughtError.complete(error); + })); + + final dynamic err = await caughtError.future; + if(err !=null ){ + print('\n $err \n'); + throw(err); + } + + expect(imageCache.pendingImageCount, 0); + expect(imageCache.statusForKey(imageProvider).untracked, true); + }); // Browser implementation does not use HTTP client but an tag. + + test('在resolve()过程中传播http客户端错误', () async { + var uncaught = false; + var url = 'asdasdasdas'; + cacheManager.throwsNotFound(url); + + await runZoned(() async { + final ImageProvider imageProvider = + CachedNetworkImageProvider(url, cacheManager: cacheManager); + final caughtError = Completer(); + FlutterError.onError = (FlutterErrorDetails details) { + throw Error(); + }; + final result = imageProvider.resolve(ImageConfiguration.empty); + result.addListener( + ImageStreamListener((ImageInfo info, bool syncCall) {}, + onError: (dynamic error, StackTrace? stackTrace) { + caughtError.complete(true); + })); + final dynamic err = await caughtError.future; + if(err !=null ){ + print('\n $err \n'); + } + expect(await caughtError.future, true); + }, zoneSpecification: ZoneSpecification( + handleUncaughtError: (Zone zone, ZoneDelegate zoneDelegate, Zone parent, + Object error, StackTrace stackTrace) { + uncaught = true; + }, + )); + expect(uncaught, false); + }); + + test('通知侦听器区块事件', () async { + final imageAvailable = Completer(); + var url = 'foo'; + var expectedResult = cacheManager.returns(url, kTransparentImage); + + final ImageProvider imageProvider = + CachedNetworkImageProvider('foo', cacheManager: cacheManager); + final result = imageProvider.resolve(ImageConfiguration.empty); + final events = []; + result.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) { + imageAvailable.complete(); + }, + onChunk: (ImageChunkEvent event) { + events.add(event); + }, + onError: (dynamic error, StackTrace? stackTrace) { + imageAvailable.completeError(error as Object, stackTrace); + }, + )); + await imageAvailable.future; + expect(events.length, expectedResult.chunks); + for (var i = 0; i < events.length; i++) { + expect( + events[i].cumulativeBytesLoaded, + math.min( + (i + 1) * expectedResult.chunkSize, kTransparentImage.length)); + expect(events[i].expectedTotalBytes, kTransparentImage.length); + } + }); // Browser loads images through not Http. + } +} + +class FakeCodec implements Codec { + @override + void dispose() {} + + @override + int get frameCount => throw UnimplementedError(); + + @override + Future getNextFrame() { + throw UnimplementedError(); + } + + @override + int get repetitionCount => throw UnimplementedError(); +} diff --git a/ohos/test_cached_network_image/lib/src/image_stream_completer_test.dart b/ohos/test_cached_network_image/lib/src/image_stream_completer_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f4d504cca4595df90ead50448c0e96af48aad1ea --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/image_stream_completer_test.dart @@ -0,0 +1,852 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import 'dart:async'; +import 'dart:typed_data'; +import 'dart:ui'; + +import 'package:flutter/cupertino.dart' hide Image; + +// import 'package:flutter/scheduler.dart' show SchedulerBinding; +import 'package:cached_network_image/cached_network_image.dart'; + +import '../common/test_page.dart'; + +class FakeFrameInfo implements FrameInfo { + const FakeFrameInfo(this._duration, this._image); + + final Duration _duration; + final Image _image; + + @override + Duration get duration => _duration; + + @override + Image get image => _image; + + int get imageHandleCount => image.debugGetOpenHandleStackTraces()!.length; + + FakeFrameInfo clone() { + return FakeFrameInfo( + _duration, + _image.clone(), + ); + } +} + +class MockCodec implements Codec { + @override + int frameCount = 1; + + @override + int repetitionCount = 1; + + int numFramesAsked = 0; + + Completer _nextFrameCompleter = Completer(); + + @override + Future getNextFrame() { + numFramesAsked += 1; + return _nextFrameCompleter.future; + } + + void completeNextFrame(FrameInfo frameInfo) { + _nextFrameCompleter.complete(frameInfo); + _nextFrameCompleter = Completer(); + } + + void failNextFrame(String err) { + _nextFrameCompleter.completeError(err); + } + + @override + void dispose() {} +} + +class FakeEventReportingImageStreamCompleter extends ImageStreamCompleter { + FakeEventReportingImageStreamCompleter( + {Stream? chunkEvents}) { + if (chunkEvents != null) { + chunkEvents.listen( + (ImageChunkEvent event) { + reportImageChunkEvent(event); + }, + ); + } + } +} + +Future createTestImage({ + int width = 1, + int height = 1, + bool cache = true, +}) async { + final Completer completer = Completer(); + decodeImageFromPixels( + Uint8List.fromList(List.filled(width * height * 4, 0)), + width, + height, + PixelFormat.rgba8888, + (Image image) { + completer.complete(image); + }, + ); + return completer.future; +} + +class ImageStreamCompleterTestPage extends TestPage { + ImageStreamCompleterTestPage(String title, {Key? key}) + : super(title: title, key: key) { + late Image image20x10; + late Image image200x100; + late Image image300x100; + test('初始化构造三个Image', () async { + image20x10 = await createTestImage(width: 20, height: 10); + image200x100 = await createTestImage(width: 200, height: 100); + image300x100 = await createTestImage(width: 300, height: 100); + }); + + // final Image image20x10= Image(width: 20, height: 10, image: NetworkImage('https://pic.lvmama.com/uploads/pc/place2/2019-04-11/30ab0015-3fbc-48a0-a5b6-f8ce8a2d0e59.jpg'),); + // final Image image200x100 = Image(width: 200, height: 100,image: NetworkImage('https://pic.lvmama.com/uploads/pc/place2/2019-04-11/b6360ae0-4536-4cf7-b16e-757ba12463f0.jpg')); + // final Image image300x100 = Image(width: 300, height: 100,image: NetworkImage('https://img0.baidu.com/it/u=4167836184,3069690856&fm=253&fmt=auto&app=120&f=JPEG?w=1200&h=800')); + + test('Codec future fails', () async { + final codecStream = StreamController(); + MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + // codecStream.addError('failure message'); + }); + + test('Completer unsubscribes to chunk events when disposed', () async { + final codecStream = StreamController(); + final chunkStream = StreamController(); + + final MultiImageStreamCompleter completer = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + chunkEvents: chunkStream.stream, + ); + + expect(chunkStream.hasListener, true); + + chunkStream.add(const ImageChunkEvent( + cumulativeBytesLoaded: 1, expectedTotalBytes: 3)); + + final ImageStreamListener listener = + ImageStreamListener((ImageInfo info, bool syncCall) {}); + // Cause the completer to dispose. + completer.addListener(listener); + completer.removeListener(listener); + + expect(chunkStream.hasListener, false); + + // The above expectation should cover this, but the point of this test is to + // make sure the completer does not assert that it's disposed and still + // receiving chunk events. Streams from the network can keep sending data + // even after evicting an image from the cache, for example. + chunkStream.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + }); + + test('Decoding starts when a listener is added after codec is ready', + () async { + final codecStream = StreamController(); + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + codecStream.add(mockCodec); + + expect(mockCodec.numFramesAsked, 0); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + expect(mockCodec.numFramesAsked, 1); + }); + + test('Decoding starts when a codec is ready after a listener is added', + () async { + final codecStream = StreamController(); + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + expect(mockCodec.numFramesAsked, 0); + + codecStream.add(mockCodec); + + expect(mockCodec.numFramesAsked, 1); + }); + + test('Adding a second codec triggers start decoding', () async { + final codecStream = StreamController(); + final firstCodec = MockCodec(); + final secondCodec = MockCodec(); + firstCodec.frameCount = 1; + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + expect(firstCodec.numFramesAsked, 0); + + codecStream.add(firstCodec); + + expect(firstCodec.numFramesAsked, 1); + + expect(secondCodec.numFramesAsked, 0); + + codecStream.add(secondCodec); + + expect(secondCodec.numFramesAsked, 1); + }); + + test('Decoding does not crash when disposed', () async { + final codecStream = StreamController(); + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + codecStream.add(mockCodec); + + expect(mockCodec.numFramesAsked, 0); + + listener(ImageInfo image, bool synchronousCall) {} + final streamListener = ImageStreamListener(listener); + imageStream.addListener(streamListener); + + expect(mockCodec.numFramesAsked, 1); + + final FrameInfo frame = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + mockCodec.completeNextFrame(frame); + imageStream.removeListener(streamListener); + }); + + test('Chunk events of base ImageStreamCompleter are delivered', () async { + final chunkEvents = []; + final streamController = StreamController(); + final ImageStreamCompleter imageStream = + FakeEventReportingImageStreamCompleter( + chunkEvents: streamController.stream, + ); + + imageStream.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onChunk: (ImageChunkEvent event) { + chunkEvents.add(event); + }, + )); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 1, expectedTotalBytes: 3)); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + + expect(chunkEvents.length, 2); + // expect(chunkEvents[0].cumulativeBytesLoaded, 1); + // expect(chunkEvents[0].expectedTotalBytes, 3); + // expect(chunkEvents[1].cumulativeBytesLoaded, 2); + // expect(chunkEvents[1].expectedTotalBytes, 3); + }); + + test( + 'Chunk events of base ImageStreamCompleter are not buffered before listener registration', + () async { + final chunkEvents = []; + final streamController = StreamController(); + final ImageStreamCompleter imageStream = + FakeEventReportingImageStreamCompleter( + chunkEvents: streamController.stream, + ); + + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 1, expectedTotalBytes: 3)); + + imageStream.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onChunk: (ImageChunkEvent event) { + chunkEvents.add(event); + }, + )); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + + expect(chunkEvents.length, 1); + // expect(chunkEvents[0].cumulativeBytesLoaded, 2); + // expect(chunkEvents[0].expectedTotalBytes, 3); + }); + + test('Chunk events of MultiImageStreamCompleter are delivered', () async { + final chunkEvents = []; + final codecStream = StreamController(); + final streamController = StreamController(); + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + chunkEvents: streamController.stream, + scale: 1.0, + ); + + imageStream.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onChunk: (ImageChunkEvent event) { + chunkEvents.add(event); + }, + )); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 1, expectedTotalBytes: 3)); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + + expect(chunkEvents.length, 2); + // expect(chunkEvents[0].cumulativeBytesLoaded, 1); + // expect(chunkEvents[0].expectedTotalBytes, 3); + // expect(chunkEvents[1].cumulativeBytesLoaded, 2); + // expect(chunkEvents[1].expectedTotalBytes, 3); + }); + + test( + 'Chunk events of MultiImageStreamCompleter are not buffered before listener registration', + () async { + final chunkEvents = []; + final codecStream = StreamController(); + final streamController = StreamController(); + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + chunkEvents: streamController.stream, + scale: 1.0, + ); + + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 1, expectedTotalBytes: 3)); + + imageStream.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onChunk: (ImageChunkEvent event) { + chunkEvents.add(event); + }, + )); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + + expect(chunkEvents.length, 1); + // expect(chunkEvents[0].cumulativeBytesLoaded, 2); + // expect(chunkEvents[0].expectedTotalBytes, 3); + }); + + test('Chunk errors are reported', () async { + final chunkEvents = []; + final codecStream = StreamController(); + final streamController = StreamController(); + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + chunkEvents: streamController.stream, + scale: 1.0, + ); + + imageStream.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onChunk: (ImageChunkEvent event) { + chunkEvents.add(event); + }, + )); + // streamController.addError(Error()); + streamController.add(const ImageChunkEvent( + cumulativeBytesLoaded: 2, expectedTotalBytes: 3)); + + expect(chunkEvents.length, 1); + // expect(chunkEvents[0].cumulativeBytesLoaded, 2); + // expect(chunkEvents[0].expectedTotalBytes, 3); + }); + + test('getNextFrame future fails', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + codecStream.add(mockCodec); + // MultiImageStreamCompleter only sets an error handler for the next + // frame future after the codec future has completed. + // Idling here lets the MultiImageStreamCompleter advance and set the + // error handler for the nextFrame future. + + // mockCodec.failNextFrame('frame completion error'); + }); + + test('ImageStream emits frame (static image)', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + final emittedImages = []; + imageStream.addListener( + ImageStreamListener((ImageInfo image, bool synchronousCall) { + emittedImages.add(image); + })); + + codecStream.add(mockCodec); + + final FrameInfo frame = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + mockCodec.completeNextFrame(frame); + + expect( + emittedImages + .every((ImageInfo info) => info.image.isCloneOf(frame.image)), + true); + }); + + test('ImageStream emits frames (animated images)', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + final emittedImages = []; + imageStream.addListener( + ImageStreamListener((ImageInfo image, bool synchronousCall) { + emittedImages.add(image); + })); + + // codecStream.add(mockCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + mockCodec.completeNextFrame(frame1); + + // We are waiting for the next animation tick, so at this point no frames + // should have been emitted. + expect(emittedImages.length, 0); + + // expect(emittedImages.single.image.isCloneOf(frame1.image), true); + + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + mockCodec.completeNextFrame(frame2); + + // The duration for the current frame was 200ms, so we don't emit the next + // frame yet even though it is ready. + expect(emittedImages.length, 1); + + // expect(emittedImages[0].image.isCloneOf(frame1.image), true); + // expect(emittedImages[1].image.isCloneOf(frame2.image), true); + }); + + test('animation wraps back', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + final emittedImages = []; + imageStream.addListener( + ImageStreamListener((ImageInfo image, bool synchronousCall) { + emittedImages.add(image); + })); + + codecStream.add(mockCodec); + + final frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + + mockCodec.completeNextFrame(frame1.clone()); + // let nextFrameFuture completefirst animation frame shows on first app frame. + mockCodec.completeNextFrame(frame2.clone()); + // let nextFrameFuture complete + mockCodec.completeNextFrame(frame1.clone()); + // let nextFrameFuture complete + + // expect(emittedImages[0].image.isCloneOf(frame1.image), true); + // expect(emittedImages[1].image.isCloneOf(frame2.image), true); + // expect(emittedImages[2].image.isCloneOf(frame1.image), true); + }); + + test('animation doesnt repeat more than specified', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = 0; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + final emittedImages = []; + imageStream.addListener( + ImageStreamListener((ImageInfo image, bool synchronousCall) { + emittedImages.add(image); + })); + + codecStream.add(mockCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + + mockCodec.completeNextFrame(frame1); + + mockCodec.completeNextFrame(frame2); + // let nextFrameFuture complete + + mockCodec.completeNextFrame(frame1); + // allow another frame to complete (but we shouldn't be asking for it as + // this animation should not repeat. + + // expect(emittedImages[0].image.isCloneOf(frame1.image), true); + // expect(emittedImages[1].image.isCloneOf(frame2.image), true); + }); + + test('frames are only decoded when there are listeners', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + final handle = imageStream.keepAlive(); + + codecStream.add(mockCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + + mockCodec.completeNextFrame(frame1); + // let nextFrameFuture complete + + mockCodec.completeNextFrame(frame2); + imageStream.removeListener(ImageStreamListener(listener)); + // let nextFrameFuture complete + + // Decoding of the 3rd frame should not start as there are no registered + // listeners to the stream + expect(mockCodec.numFramesAsked, 2); + + imageStream.addListener(ImageStreamListener(listener)); + // let nextFrameFuture complete + expect(mockCodec.numFramesAsked, 3); + + handle.dispose(); + }); + + test('multiple stream listeners', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + final emittedImages1 = []; + listener1(ImageInfo image, bool synchronousCall) { + emittedImages1.add(image); + } + + final emittedImages2 = []; + listener2(ImageInfo image, bool synchronousCall) { + emittedImages2.add(image); + } + + imageStream.addListener(ImageStreamListener(listener1)); + imageStream.addListener(ImageStreamListener(listener2)); + + codecStream.add(mockCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + + mockCodec.completeNextFrame(frame1); + // let nextFrameFuture complete + + // expect(emittedImages1.single.image.isCloneOf(frame1.image), true); + // expect(emittedImages2.single.image.isCloneOf(frame1.image), true); + + mockCodec.completeNextFrame(frame2); + // let nextFrameFuture complete + + imageStream.removeListener(ImageStreamListener(listener1)); + + // expect(emittedImages1.single.image.isCloneOf(frame1.image), true); + // expect(emittedImages2[0].image.isCloneOf(frame1.image), true); + // expect(emittedImages2[1].image.isCloneOf(frame2.image), true); + }); + + test('timer is canceled when listeners are removed', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + codecStream.add(mockCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + + mockCodec.completeNextFrame(frame1); + // let nextFrameFuture complete + + mockCodec.completeNextFrame(frame2); + // let nextFrameFuture complete + + imageStream.removeListener(ImageStreamListener(listener)); + // The test framework will fail this if there are pending timers at this + // point. + }); + + test('error handlers can intercept errors', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 1; + final codecStream = StreamController(); + + final ImageStreamCompleter streamUnderTest = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + dynamic capturedException; + errorListener(dynamic exception, StackTrace? stackTrace) { + capturedException = exception; + } + + streamUnderTest.addListener(ImageStreamListener( + (ImageInfo image, bool synchronousCall) {}, + onError: errorListener, + )); + + codecStream.add(mockCodec); + // MultiImageStreamCompleter only sets an error handler for the next + // frame future after the codec future has completed. + // Idling here lets the MultiImageStreamCompleter advance and set the + // error handler for the nextFrame future. + + // mockCodec.failNextFrame('frame completion error'); + + // No exception is passed up. + expect(capturedException, 'frame completion error'); + }); + + test('remove and add listener ', () async { + final mockCodec = MockCodec(); + mockCodec.frameCount = 3; + mockCodec.repetitionCount = 0; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + codecStream.add(mockCodec); + + // let nextFrameFuture complete + + imageStream.addListener(ImageStreamListener(listener)); + imageStream.removeListener(ImageStreamListener(listener)); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + + mockCodec.completeNextFrame(frame1); + // let nextFrameFuture complete + }); + + test( + 'Keep alive handles do not drive frames or prevent last listener callbacks', + () async { + final image10x10 = await createTestImage(width: 10, height: 10); + final mockCodec = MockCodec(); + mockCodec.frameCount = 2; + mockCodec.repetitionCount = -1; + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + var onImageCount = 0; + activeListener(ImageInfo image, bool synchronousCall) { + onImageCount += 1; + } + + var lastListenerDropped = false; + imageStream.addOnLastListenerRemovedCallback(() { + lastListenerDropped = true; + }); + + expect(lastListenerDropped, false); + final handle = imageStream.keepAlive(); + expect(lastListenerDropped, false); + // SchedulerBinding.instance + // .debugAssertNoTransientCallbacks('Only passive listeners'); + + codecStream.add(mockCodec); + + expect(onImageCount, 0); + + final frame1 = FakeFrameInfo(Duration.zero, image20x10); + mockCodec.completeNextFrame(frame1); + + // SchedulerBinding.instance + // .debugAssertNoTransientCallbacks('Only passive listeners'); + + expect(onImageCount, 0); + + imageStream.addListener(ImageStreamListener(activeListener)); + + final frame2 = FakeFrameInfo(Duration.zero, image10x10!); + mockCodec.completeNextFrame(frame2); + + // expect(SchedulerBinding.instance.transientCallbackCount, 1); + + expect(onImageCount, 1); + + imageStream.removeListener(ImageStreamListener(activeListener)); + expect(lastListenerDropped, true); + + mockCodec.completeNextFrame(frame1); + + // expect(SchedulerBinding.instance.transientCallbackCount, 1); + + expect(onImageCount, 1); + + // SchedulerBinding.instance + // .debugAssertNoTransientCallbacks('Only passive listeners'); + + mockCodec.completeNextFrame(frame2); + + // SchedulerBinding.instance + // .debugAssertNoTransientCallbacks('Only passive listeners'); + + expect(onImageCount, 1); + + handle.dispose(); + }); + + test('Multiframe image is completed before next image is shown', () async { + final firstCodec = MockCodec(); + firstCodec.frameCount = 3; + firstCodec.repetitionCount = -1; + final secondCodec = MockCodec(); + + final codecStream = StreamController(); + + final ImageStreamCompleter imageStream = MultiImageStreamCompleter( + codec: codecStream.stream, + scale: 1.0, + ); + + listener(ImageInfo image, bool synchronousCall) {} + imageStream.addListener(ImageStreamListener(listener)); + + codecStream.add(firstCodec); + + final FrameInfo frame1 = + FakeFrameInfo(const Duration(milliseconds: 200), image20x10); + final FrameInfo frame2 = + FakeFrameInfo(const Duration(milliseconds: 400), image200x100); + final FrameInfo frame3 = + FakeFrameInfo(const Duration(milliseconds: 200), image300x100); + + firstCodec.completeNextFrame(frame1); + // let nextFrameFuture complete + + firstCodec.completeNextFrame(frame2); + // let nextFrameFuture complete + + // not yet shown, but ready. + + codecStream.add(secondCodec); + // let nextFrameFuture complete + + firstCodec.completeNextFrame(frame3); + // let nextFrameFuture complete + expect(secondCodec.numFramesAsked, 0); + + // Decoding of the 3rd frame should not start as we switched images + expect(firstCodec.numFramesAsked, 3); + expect(secondCodec.numFramesAsked, 1); + }); + } +} diff --git a/ohos/test_cached_network_image/lib/src/image_widget_test.dart b/ohos/test_cached_network_image/lib/src/image_widget_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..5948987126508506b359f067dfb158a8e86663fd --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/image_widget_test.dart @@ -0,0 +1,206 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; + +import '../common/test_page.dart'; +import 'fake_cache_manager.dart'; +import 'image_data.dart'; + +class ImageWidgetTestPage extends TestPage { + ImageWidgetTestPage(String title, {Key? key}) + : super(title: title, key: key) { + FakeCacheManager cacheManager = FakeCacheManager(); + + PaintingBinding.instance.imageCache.clear(); + PaintingBinding.instance.imageCache.clearLiveImages(); + + group('test logger', () { + test('设置 CachedNetworkImage.logLevel ', () { + CachedNetworkImage.logLevel = CacheManagerLogLevel.verbose; + expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.verbose); + + CachedNetworkImage.logLevel = CacheManagerLogLevel.debug; + expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.debug); + + CachedNetworkImage.logLevel = CacheManagerLogLevel.warning; + expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.warning); + + CachedNetworkImage.logLevel = CacheManagerLogLevel.none; + expect(CachedNetworkImage.logLevel, CacheManagerLogLevel.none); + }); + }); + + group('widget tests', () { + test('成功构造 MyImageWidget', () async { + var imageUrl = '123'; + // Create the widget by telling the tester to build it. + cacheManager.returns(imageUrl, kTransparentImage); + var progressShown = false; + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onProgress: () => progressShown = true, + onError: () => thrown = true, + ); + expect(thrown, false); + expect(progressShown, true); + }); + + test('placeholder called when fail', () async { + var imageUrl = '1234'; + // Create the widget by telling the tester to build it. + cacheManager.throwsNotFound(imageUrl); + var placeholderShown = false; + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onPlaceHolder: () => placeholderShown = true, + onError: () => thrown = true, + ); + + expect(thrown, true); + expect(placeholderShown, true); + }); + + test('errorBuilder called when image fails', () async { + var imageUrl = '12345'; + cacheManager.throwsNotFound(imageUrl); + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onError: () => thrown = true, + ); + expect(thrown, true); + }); + + test("errorBuilder doesn't call when image doesn't fail", () async { + var imageUrl = '123456'; + // Create the widget by telling the tester to build it. + cacheManager.returns(imageUrl, kTransparentImage); + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onError: () => thrown = true, + ); + expect(thrown, false); + }); + + test('placeholder called when success', () async { + var imageUrl = '789'; + // Create the widget by telling the tester to build it. + cacheManager.returns(imageUrl, kTransparentImage); + var placeholderShown = false; + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onPlaceHolder: () => placeholderShown = true, + onError: () => thrown = true, + ); + expect(thrown, false); + expect(placeholderShown, true); + }); + + test('progressIndicator called several times', () async { + var imageUrl = '7891'; + // Create the widget by telling the tester to build it. + var delay = const Duration(milliseconds: 1); + var expectedResult = cacheManager.returns( + imageUrl, + kTransparentImage, + delayBetweenChunks: delay, + ); + var progressIndicatorCalled = 0; + var thrown = false; + final widget = MyImageWidget( + imageUrl: imageUrl, + cacheManager: cacheManager, + onProgress: () => progressIndicatorCalled++, + onError: () => thrown = true, + ); + for (var i = 0; i < expectedResult.chunks; i++) {} + expect(thrown, false); + expect(progressIndicatorCalled, expectedResult.chunks + 1); + }); + }); + } +} + +class MyImageWidget extends StatelessWidget { + final FakeCacheManager cacheManager; + final ProgressIndicatorBuilder? progressBuilder; + final PlaceholderWidgetBuilder? placeholderBuilder; + final LoadingErrorWidgetBuilder? errorBuilder; + final String imageUrl; + + MyImageWidget({ + Key? key, + required this.imageUrl, + required this.cacheManager, + VoidCallback? onProgress, + VoidCallback? onPlaceHolder, + VoidCallback? onError, + }) : progressBuilder = getProgress(onProgress), + placeholderBuilder = getPlaceholder(onPlaceHolder), + errorBuilder = getErrorBuilder(onError), + super(key: key); + + static ProgressIndicatorBuilder? getProgress(VoidCallback? onProgress) { + if (onProgress == null) return null; + return (context, url, progress) { + onProgress(); + return const CircularProgressIndicator(); + }; + } + + static PlaceholderWidgetBuilder? getPlaceholder(VoidCallback? onPlaceHolder) { + if (onPlaceHolder == null) return null; + return (context, url) { + onPlaceHolder(); + return const Placeholder(); + }; + } + + static LoadingErrorWidgetBuilder? getErrorBuilder(VoidCallback? onError) { + if (onError == null) return null; + return (context, error, stacktrace) { + onError(); + return const Icon(Icons.error); + }; + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Flutter Demo', + home: Scaffold( + body: Center( + child: CachedNetworkImage( + imageUrl: imageUrl, + cacheManager: cacheManager, + progressIndicatorBuilder: progressBuilder, + placeholder: placeholderBuilder, + errorWidget: errorBuilder, + ), + ), + ), + ); + } +} diff --git a/ohos/test_cached_network_image/lib/src/rendering_tester.dart b/ohos/test_cached_network_image/lib/src/rendering_tester.dart new file mode 100644 index 0000000000000000000000000000000000000000..93caf862373ec4762f0fc74de20d2a13b0d03f65 --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/rendering_tester.dart @@ -0,0 +1,317 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:flutter/gestures.dart'; +import 'package:flutter/rendering.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:flutter/services.dart'; + +export 'package:flutter/foundation.dart' show FlutterError, FlutterErrorDetails; + +class TestRenderingFlutterBinding extends BindingBase + with + SchedulerBinding, + ServicesBinding, + GestureBinding, + PaintingBinding, + SemanticsBinding, + RendererBinding { + /// Creates a binding for testing rendering library functionality. + /// + /// If [onErrors] is not null, it is called if [FlutterError] caught any errors + /// while drawing the frame. If [onErrors] is null and [FlutterError] caught at least + /// one error, this function fails the test. A test may override [onErrors] and + /// inspect errors using [takeFlutterErrorDetails]. + /// + /// Errors caught between frames will cause the test to fail unless + /// [FlutterError.onError] has been overridden. + TestRenderingFlutterBinding({this.onErrors}) { + FlutterError.onError = (FlutterErrorDetails details) { + FlutterError.dumpErrorToConsole(details); + Zone.current.parent! + .handleUncaughtError(details.exception, details.stack!); + }; + } + + final List _errors = []; + + /// A function called after drawing a frame if [FlutterError] caught any errors. + /// + /// This function is expected to inspect these errors and decide whether they + /// are expected or not. Use [takeFlutterErrorDetails] to take one error at a + /// time, or [takeAllFlutterErrorDetails] to iterate over all errors. + VoidCallback? onErrors; + + /// Returns the error least recently caught by [FlutterError] and removes it + /// from the list of captured errors. + /// + /// Returns null if no errors were captures, or if the list was exhausted by + /// calling this method repeatedly. + FlutterErrorDetails? takeFlutterErrorDetails() { + if (_errors.isEmpty) { + return null; + } + return _errors.removeAt(0); + } + + /// Returns all error details caught by [FlutterError] from least recently caught to + /// most recently caught, and removes them from the list of captured errors. + /// + /// The returned iterable takes errors lazily. If, for example, you iterate over 2 + /// errors, but there are 5 errors total, this binding will still fail the test. + /// Tests are expected to take and inspect all errors. + Iterable takeAllFlutterErrorDetails() sync* { + // sync* and yield are used for lazy evaluation. Otherwise, the list would be + // drained eagerly and allow a test pass with unexpected errors. + while (_errors.isNotEmpty) { + yield _errors.removeAt(0); + } + } + + /// Returns all exceptions caught by [FlutterError] from least recently caught to + /// most recently caught, and removes them from the list of captured errors. + /// + /// The returned iterable takes errors lazily. If, for example, you iterate over 2 + /// errors, but there are 5 errors total, this binding will still fail the test. + /// Tests are expected to take and inspect all errors. + Iterable takeAllFlutterExceptions() sync* { + // sync* and yield are used for lazy evaluation. Otherwise, the list would be + // drained eagerly and allow a test pass with unexpected errors. + while (_errors.isNotEmpty) { + yield _errors.removeAt(0).exception; + } + } + + @override + void drawFrame() { + final oldErrorHandler = FlutterError.onError; + FlutterError.onError = (FlutterErrorDetails details) { + _errors.add(details); + }; + + FlutterError.onError = oldErrorHandler; + if (_errors.isNotEmpty) { + if (onErrors != null) { + onErrors!(); + if (_errors.isNotEmpty) { + _errors.forEach(FlutterError.dumpErrorToConsole); + throw ('There are more errors than the test inspected using TestRenderingFlutterBinding.takeFlutterErrorDetails.'); + } + } else { + _errors.forEach(FlutterError.dumpErrorToConsole); + throw ('Caught error while rendering frame. See preceding logs for details.'); + } + } + } +} + +final TestRenderingFlutterBinding _renderer = TestRenderingFlutterBinding(); + +TestRenderingFlutterBinding get renderer => _renderer; + +/// Place the box in the render tree, at the given size and with the given +/// alignment on the screen. +/// +/// If you've updated `box` and want to lay it out again, use [pumpFrame]. +/// +/// Once a particular [RenderBox] has been passed to [layout], it cannot easily +/// be put in a different place in the tree or passed to [layout] again, because +/// [layout] places the given object into another [RenderBox] which you would +/// need to unparent it from (but that box isn't itself made available). +/// +/// The EnginePhase must not be [EnginePhase.build], since the rendering layer +/// has no build phase. +/// +/// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError]. +void layout( + RenderBox box, { + BoxConstraints? constraints, + Alignment alignment = Alignment.center, + VoidCallback? onErrors, +}) { + assert(box.parent == + null); // We stick the box in another, so you can't reuse it easily, sorry. + + renderer.renderView.child = null; + if (constraints != null) { + box = RenderPositionedBox( + alignment: alignment, + child: RenderConstrainedBox( + additionalConstraints: constraints, + child: box, + ), + ); + } + renderer.renderView.child = box; + + pumpFrame(onErrors: onErrors); +} + +/// Pumps a single frame. +/// +/// If `onErrors` is not null, it is set as [TestRenderingFlutterBinding.onError]. +void pumpFrame({VoidCallback? onErrors}) { + assert(renderer.renderView.child != null); // call layout() first! + + if (onErrors != null) { + renderer.onErrors = onErrors; + } + + renderer.drawFrame(); +} + +class TestCallbackPainter extends CustomPainter { + const TestCallbackPainter({required this.onPaint}); + + final VoidCallback onPaint; + + @override + void paint(Canvas canvas, Size size) { + onPaint(); + } + + @override + bool shouldRepaint(TestCallbackPainter oldPainter) => true; +} + +class RenderSizedBox extends RenderBox { + RenderSizedBox(this._size); + + final Size _size; + + @override + double computeMinIntrinsicWidth(double height) { + return _size.width; + } + + @override + double computeMaxIntrinsicWidth(double height) { + return _size.width; + } + + @override + double computeMinIntrinsicHeight(double width) { + return _size.height; + } + + @override + double computeMaxIntrinsicHeight(double width) { + return _size.height; + } + + @override + bool get sizedByParent => true; + + @override + void performResize() { + size = constraints.constrain(_size); + } + + @override + void performLayout() {} + + @override + bool hitTestSelf(Offset position) => true; +} + +class FakeTickerProvider implements TickerProvider { + @override + Ticker createTicker(TickerCallback onTick, [bool disableAnimations = false]) { + return FakeTicker(); + } +} + +class FakeTicker implements Ticker { + @override + bool muted = false; + + @override + void absorbTicker(Ticker originalTicker) {} + + @override + String? get debugLabel => null; + + @override + bool get isActive => throw UnimplementedError(); + + @override + bool get isTicking => throw UnimplementedError(); + + @override + bool get scheduled => throw UnimplementedError(); + + @override + bool get shouldScheduleTick => throw UnimplementedError(); + + @override + void dispose() {} + + @override + void scheduleTick({bool rescheduling = false}) {} + + @override + TickerFuture start() { + throw UnimplementedError(); + } + + @override + void stop({bool canceled = false}) {} + + @override + void unscheduleTick() {} + + @override + String toString({bool debugIncludeStack = false}) => super.toString(); + + @override + DiagnosticsNode describeForError(String name) { + return DiagnosticsProperty(name, this, + style: DiagnosticsTreeStyle.errorProperty); + } +} + +class TestClipPaintingContext extends PaintingContext { + TestClipPaintingContext() : super(ContainerLayer(), Rect.zero); + + @override + ClipRectLayer? pushClipRect( + bool needsCompositing, + Offset offset, + Rect clipRect, + PaintingContextCallback painter, { + Clip clipBehavior = Clip.hardEdge, + ClipRectLayer? oldLayer, + }) { + this.clipBehavior = clipBehavior; + return null; + } + + Clip clipBehavior = Clip.none; +} + +void expectOverflowedErrors() { + final errorDetails = renderer.takeFlutterErrorDetails(); + final overflowed = errorDetails.toString().contains('overflowed'); + if (!overflowed) { + FlutterError.reportError(errorDetails!); + } +} + +RenderConstrainedBox get box200x200 => RenderConstrainedBox( + additionalConstraints: + const BoxConstraints.tightFor(height: 200.0, width: 200.0)); diff --git a/ohos/test_cached_network_image/lib/src/ui_apge.dart b/ohos/test_cached_network_image/lib/src/ui_apge.dart new file mode 100644 index 0000000000000000000000000000000000000000..7d64a98037bc3f3f6feedcd5612138eb5ecc2822 --- /dev/null +++ b/ohos/test_cached_network_image/lib/src/ui_apge.dart @@ -0,0 +1,189 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:cached_network_image/cached_network_image.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_blurhash/flutter_blurhash.dart'; + +/// Demonstrates a [StatelessWidget] containing [CachedNetworkImage] +class BasicContent extends StatelessWidget { + const BasicContent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('演示包含[CachedNetworkImage]的[StatelessWidget]'), + ), + body: SingleChildScrollView( + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + _sizedContainer( + const Image( + image: CachedNetworkImageProvider( + 'http://via.placeholder.com/350x150', + ), + ), + ), + _sizedContainer( + CachedNetworkImage( + progressIndicatorBuilder: (context, url, progress) => Center( + child: CircularProgressIndicator( + value: progress.progress, + ), + ), + imageUrl: 'http://images.unsplash.com/photo-1532264523420-881a47db012d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9', + ), + ), + _sizedContainer( + CachedNetworkImage( + placeholder: (context, url) => const CircularProgressIndicator(), + imageUrl: 'http://via.placeholder.com/200x150', + ), + ), + _sizedContainer( + CachedNetworkImage( + imageUrl: 'http://via.placeholder.com/300x150', + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + image: DecorationImage( + image: imageProvider, + fit: BoxFit.cover, + colorFilter: const ColorFilter.mode( + Colors.red, + BlendMode.colorBurn, + ), + ), + ), + ), + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), + CachedNetworkImage( + imageUrl: 'http://via.placeholder.com/300x300', + placeholder: (context, url) => const CircleAvatar( + backgroundColor: Colors.amber, + radius: 150, + ), + imageBuilder: (context, image) => CircleAvatar( + backgroundImage: image, + radius: 150, + ), + ), + _sizedContainer( + CachedNetworkImage( + imageUrl: 'http://notAvalid.uri', + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), + _sizedContainer( + CachedNetworkImage( + imageUrl: 'not a uri at all', + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + ), + ), + _sizedContainer( + CachedNetworkImage( + maxHeightDiskCache: 10, + imageUrl: 'http://via.placeholder.com/350x200', + placeholder: (context, url) => const CircularProgressIndicator(), + errorWidget: (context, url, error) => const Icon(Icons.error), + fadeOutDuration: const Duration(seconds: 1), + fadeInDuration: const Duration(seconds: 3), + ), + ), + ], + ), + ), + ), + ); + } + + Widget _sizedContainer(Widget child) { + return SizedBox( + width: 300.0, + height: 150.0, + child: Center(child: child), + ); + } +} + +/// Demonstrates a [ListView] containing [CachedNetworkImage] +class ListContent extends StatelessWidget { + const ListContent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('演示包含[CachedNetworkImage]的[ListView]'), + ), + body: ListView.builder( + itemBuilder: (BuildContext context, int index) => Card( + child: Column( + children: [ + CachedNetworkImage( + imageUrl: 'http://loremflickr.com/320/240/music?lock=$index', + placeholder: (BuildContext context, String url) => Container( + width: 320, + height: 240, + color: Colors.purple, + ), + ), + ], + ), + ), + itemCount: 250, + ), + ); + } +} + +/// Demonstrates a [GridView] containing [CachedNetworkImage] +class GridContent extends StatelessWidget { + const GridContent({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text('演示包含[CachedNetworkImage]的[GridView]'), + ), + body: GridView.builder( + itemCount: 250, + gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(crossAxisCount: 3), + itemBuilder: (BuildContext context, int index) => CachedNetworkImage( + imageUrl: 'http://loremflickr.com/100/100/music?lock=$index', + placeholder: _loader, + errorWidget: _error, + ), + ), + ); + } + + Widget _loader(BuildContext context, String url) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + Widget _error(BuildContext context, String url, dynamic error) { + return const Center(child: Icon(Icons.error)); + } +} diff --git a/ohos/test_cached_network_image/ohos/.gitignore b/ohos/test_cached_network_image/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/AppScope/app.json5 b/ohos/test_cached_network_image/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..3b29861281d50c1f317c854cefa6e2272b5c2ac2 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/AppScope/app.json5 @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "app": { + "bundleName": "com.example.test_cached_network_image", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_cached_network_image/ohos/AppScope/resources/base/element/string.json b/ohos/test_cached_network_image/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..703bc0744832adda1b582cee8f4d4986f88bda9c --- /dev/null +++ b/ohos/test_cached_network_image/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_cached_network_image" + } + ] +} diff --git a/ohos/test_cached_network_image/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_cached_network_image/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_cached_network_image/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_cached_network_image/ohos/build-profile.json5 b/ohos/test_cached_network_image/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f601e0a56f5824c41ebfecd4d7d182364b347412 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_cached_network_image.cer", + "storePassword": "0000001B588F26D320309278B9A2CB11CC66E559E9B5C716351F1207729FD8D15356DAFEF0F2EF1E22A41D", + "keyAlias": "debugKey", + "keyPassword": "0000001B2044D916B8B3022932CF58FC4FFE6D00C92F9C81F24FDE0BB4890AB294B442A75BBAC83E1F1C49", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_cached_network_image.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_cached_network_image.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_cached_network_image/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_cached_network_image/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_cached_network_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_cached_network_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_cached_network_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_cached_network_image/ohos/dependencies/rollup.tgz b/ohos/test_cached_network_image/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_cached_network_image/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_cached_network_image/ohos/entry/.gitignore b/ohos/test_cached_network_image/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/build-profile.json5 b/ohos/test_cached_network_image/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/hvigorfile.ts b/ohos/test_cached_network_image/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_cached_network_image/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_cached_network_image/ohos/entry/oh-package.json5 b/ohos/test_cached_network_image/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7f1921fc18843d56f091ff058300496a48bd554a --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har", + "@ohos/path_provider": "file:../har/path_provider.har" + } +} diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_cached_network_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..f442fca52ad19b04b9969d648bf549273b0a6c9b --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import PathProviderPlugin from '@ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + this.addPlugin(new PathProviderPlugin()) + } +} diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_cached_network_image/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/module.json5 b/ohos/test_cached_network_image/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_cached_network_image/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_cached_network_image/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/module.json5 b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_cached_network_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_cached_network_image/ohos/har/path_provider.har b/ohos/test_cached_network_image/ohos/har/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..8c59d9becc7b85514cdf262b804216c32a856cbb Binary files /dev/null and b/ohos/test_cached_network_image/ohos/har/path_provider.har differ diff --git a/ohos/test_cached_network_image/ohos/hvigor/hvigor-config.json5 b/ohos/test_cached_network_image/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_cached_network_image/ohos/hvigor/hvigor-wrapper.js b/ohos/test_cached_network_image/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..0a613641a9b7aad1c1c0208a9d1c97f0dba9aa79 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,17 @@ + +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/hvigorfile.ts b/ohos/test_cached_network_image/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_cached_network_image/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/hvigorw b/ohos/test_cached_network_image/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_cached_network_image/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_cached_network_image/ohos/hvigorw.bat b/ohos/test_cached_network_image/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..a4899d6616d667f4ac7e8c24c566759dec7a34cb --- /dev/null +++ b/ohos/test_cached_network_image/ohos/hvigorw.bat @@ -0,0 +1,77 @@ +::Copyright (c) 2023 Huawei Device Co., Ltd. +::Licensed under the Apache License, Version 2.0 (the "License"); +::you may not use this file except in compliance with the License. +::You may obtain a copy of the License at +:: +:: http://www.apache.org/licenses/LICENSE-2.0 +:: +::Unless required by applicable law or agreed to in writing, software +::distributed under the License is distributed on an "AS IS" BASIS, +::WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +::See the License for the specific language governing permissions and +::limitations under the License. + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_cached_network_image/ohos/oh-package-lock.json5 b/ohos/test_cached_network_image/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..cc6c8ab65b2c54d62f729316c8bd999cbfd341aa --- /dev/null +++ b/ohos/test_cached_network_image/ohos/oh-package-lock.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_cached_network_image/ohos/oh-package.json5 b/ohos/test_cached_network_image/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8c2aef996856a664fd5264a323e062d70b52b42c --- /dev/null +++ b/ohos/test_cached_network_image/ohos/oh-package.json5 @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_cached_network_image/pubspec.yaml b/ohos/test_cached_network_image/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..42fc0a105293333cb8487cd38e8cdd844374a280 --- /dev/null +++ b/ohos/test_cached_network_image/pubspec.yaml @@ -0,0 +1,41 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_cached_network_image +description: A new Flutter project. +publish_to: none +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + dio: ^5.3.3 + cached_network_image: 3.2.3 + flutter_cache_manager: 3.3.1 + mocktail: ^0.1.1 + path_provider_platform_interface: ^2.0.0 + path_provider_ohos: + path: ./lib/path_provider_ohos + path_provider: + path: ./lib/path_provider-2.0.0 +flutter: + uses-material-design: true +dependency_overrides: + path_provider_ohos: + path: ./lib/path_provider_ohos + path_provider: + path: ./lib/path_provider-2.0.0 \ No newline at end of file diff --git a/ohos/test_collection/.gitignore b/ohos/test_collection/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_collection/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_collection/.metadata b/ohos/test_collection/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..c64177774df6a3ceb0f67e70374ac42f58b6bccb --- /dev/null +++ b/ohos/test_collection/.metadata @@ -0,0 +1,45 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_collection/README.md b/ohos/test_collection/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_collection/analysis_options.yaml b/ohos/test_collection/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_collection/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_collection/lib/common/base_page.dart b/ohos/test_collection/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..987585c34978cebd1560dbba1ff3f5fb542512ef --- /dev/null +++ b/ohos/test_collection/lib/common/base_page.dart @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_collection/lib/common/item_widget.dart b/ohos/test_collection/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..2f6c380665461e81d7085bfae36e837c2c552a85 --- /dev/null +++ b/ohos/test_collection/lib/common/item_widget.dart @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_collection/lib/common/main_item_widget.dart b/ohos/test_collection/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c49255738e5a7c8d934dd6813ffd853e960c839c --- /dev/null +++ b/ohos/test_collection/lib/common/main_item_widget.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_collection/lib/common/test_model_app.dart b/ohos/test_collection/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..045851633e9cad7d8ff09f2836930125c71216ee --- /dev/null +++ b/ohos/test_collection/lib/common/test_model_app.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_collection/lib/common/test_page.dart b/ohos/test_collection/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_collection/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_collection/lib/common/test_route.dart b/ohos/test_collection/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_collection/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_collection/lib/main.dart b/ohos/test_collection/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..1a0b7114fe77d513e31c24fc6e5d4f1e95a0e64f --- /dev/null +++ b/ohos/test_collection/lib/main.dart @@ -0,0 +1,67 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; +import 'package:test_collection/page/algorithms_test.dart'; +import 'package:test_collection/page/boollist_test.dart'; +import 'package:test_collection/page/canonicalized_map_test.dart'; +import 'package:test_collection/page/comparators_test.dart'; +import 'package:test_collection/page/equality_map_test.dart'; +import 'package:test_collection/page/equality_set_test.dart'; +import 'package:test_collection/page/equality_test.dart'; +import 'package:test_collection/page/functions_test.dart'; +import 'package:test_collection/page/ignore_ascii_case_test.dart'; +import 'package:test_collection/page/iterable_test_page.dart'; +import 'package:test_collection/page/iterable_zip_test.dart'; +import 'package:test_collection/page/list_test.dart'; +import 'package:test_collection/page/map_test.dart'; +import 'package:test_collection/page/priority_queue_test.dart'; +import 'package:test_collection/page/queue_list_test.dart'; +import 'package:test_collection/page/union_set_controller_test.dart'; +import 'package:test_collection/page/union_set_test.dart'; +import 'package:test_collection/page/unmodifiable_collection_test.dart'; +import 'package:test_collection/page/wrapper_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + final app = [ + MainItem('CombinedIterableView', + CombinedIterableViewTestPage('CombinedIterableView')), + MainItem('CombinedListView', CombinedListViewTestPage('CombinedListView')), + MainItem('CombinedMapView', CombinedMapViewTestPage('CombinedMapView')), + MainItem('Algorithms', AlgorithmsTestPage('Algorithms')), + MainItem('BoolList', BoolListTestPage('BoolList')), + MainItem('CanonicalizedMap', CanonicalizedMapTestPage('CanonicalizedMap')), + MainItem('comparators', ComparatorsTestPage('comparators')), + MainItem('EqualityMap', EqualityMapTestPage('EqualityMap')), + MainItem('EqualitySet', EqualitySetTestPage('EqualitySet')), + MainItem('Equality', EqualityTestPage('Equality')), + MainItem('Functions', FunctionsTestPage('Functions')), + MainItem('IgnoreAsciiCase', IgnoreAsciiCaseTestPage('IgnoreAsciiCase')), + MainItem('IterableZip', IterableZipTestPage('IterableZip')), + MainItem('PriorityQueue', PriorityQueueTestPage('PriorityQueue')), + MainItem('QueueList', QueueListTestPage('QueueList')), + MainItem( + 'UnionSetController', UnionSetControllerTestPage('UnionSetController')), + MainItem('UnionSet', UnionSetTestPage('UnionSet')), + MainItem('UnmodifiableCollection', + UnmodifiableCollectionTestPage('UnmodifiableCollection')), + MainItem( + 'WrapperTestPage', WrapperTestPage('WrapperTestPage')), + ]; + + runApp(TestModelApp(appName: 'collection', data: app)); +} diff --git a/ohos/test_collection/lib/page/algorithms_test.dart b/ohos/test_collection/lib/page/algorithms_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8c7cb86b1f4d09e152061eadc0072c4c080c8c86 --- /dev/null +++ b/ohos/test_collection/lib/page/algorithms_test.dart @@ -0,0 +1,366 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/// Tests algorithm utilities. +import 'dart:math'; + +import 'package:collection/collection.dart'; +import 'package:collection/src/algorithms.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class AlgorithmsTestPage extends TestPage { + AlgorithmsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('Shuffle[0]', () { + testShuffle([]); + }); + test('Shuffle[1]', () { + testShuffle([1]); + }); + test('Shuffle[1,2,3]', () { + testShuffle([1, 2, 3]); + }); + test('Shuffle[1, 2, 3, 4, 5, 1, 3, 5, 7, 9]', () { + testShuffle([1, 2, 3, 4, 5, 1, 3, 5, 7, 9]); + }); + test('Shuffle shuffles', () { + var l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + var c = l.toList(); + var count = 0; + for (;;) { + shuffle(l); + if (!const ListEquality().equals(c, l)) return; + // Odds of not changing the order should be one in ~ 16! ~= 2e+13. + // Repeat this 10 times, and the odds of accidentally shuffling to the + // same result every time is disappearingly tiny. + count++; + // If this happens even once, it's ok to report it. + print('Failed shuffle $count times'); + if (count == 10) fail("Shuffle didn't change order."); + } + }); + test('Shuffle 子列表', () { + var l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; + var c = l.toList(); + shuffle(l, 4, 12); + const IterableEquality().equals(l.getRange(0, 4), c.getRange(0, 4)); + expect(const IterableEquality().equals(l.getRange(12, 16), c.getRange(12, 16)), true); + expect(const UnorderedIterableEquality().equals(l.getRange(4, 12), c.getRange(4, 12)), true); + }); + + test('binarySearch([], 2)', () { + expect(binarySearch([], 2), -1); + }); + + test('binarySearch([5], 2)', () { + binarySearch([5], 2); + }); + + test('binarySearch([0, 5, 10], -1)', () { + binarySearch([0, 5, 10], -1); + binarySearch([0, 5, 10], 0); + binarySearch([0, 5, 10], 2); + }); + + test('binarySearch([], C(2)', () { + binarySearch([], C(2), compare: compareC); + }); + + test('binarySearch(l1, C(2)', () { + var l1 = [C(5)]; + binarySearch(l1, C(2), compare: compareC); + }); + + test('binarySearch(l3, C(2)', () { + var l3 = [C(0), C(5), C(10)]; + binarySearch(l3, C(2), compare: compareC); + }); + + test('lowerBound([], 2)', () { + lowerBound([], 2); + }); + + test('lowerBound([5], 5)', () { + lowerBound([5], 5); + }); + + test('lowerBound([0, 5, 10], 2)', () { + lowerBound([0, 5, 10], 2); + }); + + test('lowerBound([0, 5, 5, 5, 10], 5)', () { + lowerBound([0, 5, 5, 5, 10], 5); + }); + + test('lowerBound([], C(2), compare: compareC)', () { + lowerBound([], C(2), compare: compareC); + }); + + test('lowerBound(l1, C(5), compare: compareC)', () { + var l1 = [C(5)]; + lowerBound(l1, C(5), compare: compareC); + }); + + test('lowerBound(l3, C(2), compare: compareC)', () { + var l3 = [C(0), C(5), C(10)]; + lowerBound(l3, C(2), compare: compareC); + }); + + test('lowerBound(l2, C(5), compare: compareC)', () { + var l2 = [C(0), C(5), C(5), C(5), C(10)]; + lowerBound(l2, C(5), compare: compareC); + }); + + void testSort(String name, void Function(List elements, [int? start, int? end]) sort) { + test('${name}Random', () { + var random = Random(); + for (var i = 0; i < 250; i += 10) { + var list = [ + for (var j = 0; j < i; j++) random.nextInt(25) // Expect some equal elements. + ]; + sort(list); + for (var j = 1; j < i; j++) { + expect(list[j - 1], list[j]); + } + } + }); + + test('list.sort()', () { + var list = [6, 5, 4, 3, 2, 1]; + sort(list, 2, 4); + print(list); + sort(list, 1, 1); + print(list); + sort(list, 4, 6); + print(list); + sort(list, 0, 2); + print(list); + sort(list, 0, 6); + print(list); + }); + } + + int intId(int x) => x; + int intCompare(int a, int b) => a - b; + testSort('insertionSortBy', (list, [start, end]) { + insertionSortBy(list, intId, intCompare, start ?? 0, end ?? list.length); + }); + testSort('mergeSort compare', (list, [start, end]) { + mergeSort(list, start: start ?? 0, end: end ?? list.length, compare: intCompare); + }); + testSort('mergeSort comparable', (list, [start, end]) { + mergeSort(list, start: start ?? 0, end: end ?? list.length); + }); + testSort('mergeSortBy', (list, [start, end]) { + mergeSortBy(list, intId, intCompare, start ?? 0, end ?? list.length); + }); + testSort('quickSort', (list, [start, end]) { + quickSort(list, intCompare, start ?? 0, end ?? list.length); + }); + testSort('quickSortBy', (list, [start, end]) { + quickSortBy(list, intId, intCompare, start ?? 0, end ?? list.length); + }); + test('MergeSortSpecialCases', () { + for (var size in [511, 512, 513]) { + // All equal. + var list = List.generate(size, (i) => OC(0, i)); + mergeSort(list); + for (var i = 0; i < size; i++) { + list[i].order; + } + // All but one equal, first. + list[0] = OC(1, 0); + for (var i = 1; i < size; i++) { + list[i] = OC(0, i); + } + mergeSort(list); + for (var i = 0; i < size - 1; i++) { + list[i].order; + } + list[size - 1].order; + + // All but one equal, last. + for (var i = 0; i < size - 1; i++) { + list[i] = OC(0, i); + } + list[size - 1] = OC(-1, size - 1); + mergeSort(list); + list[0].order; + for (var i = 1; i < size; i++) { + list[i].order; + } + + // Reversed. + for (var i = 0; i < size; i++) { + list[i] = OC(size - 1 - i, i); + } + mergeSort(list); + for (var i = 0; i < size; i++) { + list[i].id; + list[i].order; + } + } + }); + + void testSortBy( + String name, void Function(List elements, K Function(T element) keyOf, int Function(K a, K b) compare, [int start, int end]) sort) { + for (var n in [0, 1, 2, 10, 75, 250]) { + var name2 = name; + test('$name2: Same #$n', () { + var list = List.generate(n, (i) => OC(i, 0)); + // Should succeed. Bad implementations of, e.g., quicksort can diverge. + sort(list, ocOrder, compareInt); + }); + test('$name: Pre-sorted #$n', () { + var list = List.generate(n, (i) => OC(-i, i)); + var expected = list.toList(); + sort(list, ocOrder, compareInt); + // Elements have not moved. + expect(list, expected); + }); + test('$name: Reverse-sorted #$n', () { + var list = List.generate(n, (i) => OC(i, -i)); + sort(list, ocOrder, compareInt); + expectSorted(list, ocOrder, compareInt); + }); + test('$name: Random #$n', () { + var random = Random(); + var list = List.generate(n, (i) => OC(i, random.nextInt(n))); + sort(list, ocOrder, compareInt); + expectSorted(list, ocOrder, compareInt); + }); + test('$name: Sublist #$n', () { + var random = Random(); + var list = List.generate(n, (i) => OC(i, random.nextInt(n))); + var original = list.toList(); + var start = n ~/ 4; + var end = start * 3; + sort(list, ocOrder, compareInt, start, end); + expectSorted(list, ocOrder, compareInt, start, end); + expect(list.sublist(0, start), original.sublist(0, start)); + expect(list.sublist(end), original.sublist(end)); + }); + } + } + + testSortBy('insertionSort', insertionSortBy); + testSortBy('mergeSort', mergeSortBy); + testSortBy('quickSortBy', quickSortBy); + + test('MergeSortPreservesOrder', () { + var random = Random(); + // Small case where only insertion call is called, + // larger case where the internal moving insertion sort is used + // larger cases with multiple splittings, numbers just around a power of 2. + for (var size in [8, 50, 511, 512, 513]) { + // Class OC compares using id. + // With size elements with id's in the range 0..size/4, a number of + // collisions are guaranteed. These should be sorted so that the 'order' + // part of the objects are still in order. + var list = [for (var i = 0; i < size; i++) OC(random.nextInt(size >> 2), i)]; + mergeSort(list); + var prev = list[0]; + for (var i = 1; i < size; i++) { + var next = list[i]; + expect(prev.id, next.id); + if (next.id == prev.id) { + expect(prev.order, next.order); + } + prev = next; + } + // Reverse compare on part of list. + List copy = list.toList(); + var min = size >> 2; + var max = size - min; + mergeSort(list, start: min, end: max, compare: (a, b) => b.compareTo(a)); + prev = list[min]; + for (var i = min + 1; i < max; i++) { + var next = list[i]; + expect(prev.id, next.id); + if (next.id == prev.id) { + expect(prev.order, next.order); + } + prev = next; + } + // Equals on OC objects is identity, so this means the parts before min, + // and the parts after max, didn't change at all. + expect(list.sublist(0, min), copy.sublist(0, min)); + expect(list.sublist(max), copy.sublist(max)); + } + }); + + test('Reverse', () { + var l = [6, 5, 4, 3, 2, 1]; + reverse(l, 2, 4); + expect(l, [6, 5, 3, 4, 2, 1]); + reverse(l, 1, 1); + expect(l, [6, 5, 3, 4, 2, 1]); + reverse(l, 4, 6); + expect(l, [6, 5, 3, 4, 1, 2]); + reverse(l, 0, 2); + expect(l, [5, 6, 3, 4, 1, 2]); + reverse(l, 0, 6); + expect(l, [2, 1, 4, 3, 6, 5]); + }); + } + + int compareC(C one, C other) => one.id - other.id; + + int cId(C c) => c.id; + + int ocId(OC oc) => oc.id; + + int ocOrder(OC oc) => oc.order; + + int compareInt(int a, int b) => a - b; + + /// Check that a list is sorted according to [compare] of [keyOf] of elements. + void expectSorted(List list, K Function(T element) keyOf, int Function(K a, K b) compare, [int start = 0, int? end]) { + end ??= list.length; + if (start == end) return; + var prev = keyOf(list[start]); + for (var i = start + 1; i < end; i++) { + var next = keyOf(list[i]); + expect(compare(prev, next), null); + prev = next; + } + } + + void testShuffle(List list) { + var copy = list.toList(); + shuffle(list); + expect(UnorderedIterableEquality().equals(list, copy), true); + } +} + +class C { + final int id; + + C(this.id); +} + +/// Class naturally ordered by its first constructor argument. +class OC implements Comparable { + final int id; + final int order; + + OC(this.id, this.order); + + @override + int compareTo(OC other) => id - other.id; + + @override + String toString() => 'OC[$id,$order]'; +} diff --git a/ohos/test_collection/lib/page/boollist_test.dart b/ohos/test_collection/lib/page/boollist_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c9bf4fa93a876c181b85eb40ca5ade91c8ca368c --- /dev/null +++ b/ohos/test_collection/lib/page/boollist_test.dart @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Tests for BoolList. + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class BoolListTestPage extends TestPage { + BoolListTestPage(String title, {Key? key}) : super(title: title, key: key) { + test('BoolList()', () { + expect(BoolList(1024, fill: false), List.filled(1024, false)); + + expect(BoolList(1024, fill: true), List.filled(1024, true)); + }); + + test('BoolList.empty()', () { + expect(BoolList.empty(growable: true, capacity: 1024), []); + + expect(BoolList.empty(growable: false, capacity: 1024), []); + }); + + test('BoolList.generate()', () { + expect( + BoolList.generate(1024, generator), + List.generate(1024, generator), + ); + }); + + test('BoolList.of()', () { + var src = List.generate(1024, generator); + expect(BoolList.of(src), src); + }); + + group('BoolList参数批量测试', () { + test('长度获取错误, 此处应为X', () async { + var b = BoolList(1024, fill: false); + + b[-1]; + + b[1024]; + }); + }); + + test('BoolList.length', () { + var b = BoolList(1024, fill: true, growable: true); + + b.length = 768; + expect(b, List.filled(768, true)); + + b.length = 128; + expect(b, List.filled(128, true)); + + b.length = 0; + expect(b, []); + + b = BoolList(256, fill: true, growable: true); + + b.length = 384; + expect(b, List.filled(384, false)..fillRange(0, 256, true)); + + b.length = 2048; + expect(b, List.filled(2048, false)..fillRange(0, 256, true)); + + b = BoolList(0, growable: true); + expect(b.length, 0); + + b.length = 256; + expect(b, List.filled(256, false)); + }); + + test('BoolList.fillRange', () { + BoolList(1024)..fillRange(32, 64, true); + List.filled(1024, false)..fillRange(32, 64, true); + + BoolList.generate(1024, (i) => true)..fillRange(32, 64, false); + List.filled(1024, true)..fillRange(32, 64, false); + + BoolList(1024)..fillRange(32, 128, true); + List.filled(1024, false)..fillRange(32, 128, true); + + BoolList.generate(1024, (i) => true)..fillRange(32, 128, false); + List.filled(1024, true)..fillRange(32, 128, false); + expect(List.filled(1024, true)..fillRange(32, 128, false), null); + }); + + test('BoolList.iterator', () { + var b = BoolList.generate(1024, generator); + var iter = b.iterator; + + expect(iter.current, false); + for (var i = 0; i < 1024; i++) { + expect(iter.moveNext(), true); + + expect(iter.current, generator(i)); + } + + expect(iter.moveNext(), false); + expect(iter.current, false); + + b = BoolList(1024, fill: true, growable: true); + + iter = b.iterator; + + iter.moveNext(); + + }); + } + + bool generator(int index) { + if (index < 512) { + return index.isEven; + } + return false; + } +} diff --git a/ohos/test_collection/lib/page/canonicalized_map_test.dart b/ohos/test_collection/lib/page/canonicalized_map_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b6634bab69d831e75fb4660d7fdf0359c1adf38c --- /dev/null +++ b/ohos/test_collection/lib/page/canonicalized_map_test.dart @@ -0,0 +1,179 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class CanonicalizedMapTestPage extends TestPage { + CanonicalizedMapTestPage(String title, {Key? key}) + : super(title: title, key: key) { + group('map的key有格式要求', () { + late CanonicalizedMap map; + + map = CanonicalizedMap(int.parse, isValidKey: RegExp(r'^\d+$').hasMatch); + + test("CanonicalizedMap[key] -> map['1'], map['01']", () { + map['1'] = 'value'; + final x = map['01']; + map['foo'] = 'value'; + expect(map['foo'], null); + expect(map.containsKey('foo'), true); + map.length; + expect(map['foo'], null); + }); + + test('CanonicalizedMap.addAll', () { + map.addAll({'1': 'value 1', '2': 'value 2', '3': 'value 3'}); + map['01']; + map['02']; + map['03']; + }); + + test('CanonicalizedMap.length', () { + map.addAll({'1': 'value 1', '01': 'value 2', '001': 'value 3'}); + map.length; + map['0001']; + }); + + test('CanonicalizedMap.clear()', () { + map.addAll({'1': 'value 1', '2': 'value 2', '3': 'value 3'}); + expect(map, null); + map.clear(); + map.isEmpty; + }); + + test('CanonicalizedMap.containsKey()', () { + map['1'] = 'value'; + expect(map.containsKey('01'), true); + expect(map.containsKey('2'), false); + + expect(map.containsKey('foo'), false); + }); + + test('CanonicalizedMap.putIfAbsent', () { + map['1'] = 'value'; + map.putIfAbsent('01', () => throw Exception("shouldn't run")); + map.putIfAbsent('2', () => 'new value'); + }); + + test('CanonicalizedMap.remove', () { + map['1'] = 'value'; + expect(map.remove('2'), null); + map.remove('01'); + map.isEmpty; + map.remove('foo'); + }); + + test('CanonicalizedMap.containsValue', () { + map['1'] = 'value'; + expect(map.containsValue('value'), true); + expect(map.containsValue('not value'), false); + }); + + test('CanonicalizedMap.isEmpty', () { + expect(map.isEmpty, true); + map['1'] = 'value'; + expect(map.isEmpty, false); + map.remove('01'); + expect(map.isEmpty, true); + }); + + test("CanonicalizedMap.isNotEmpty", () { + expect(map.isNotEmpty, false); + map['1'] = 'value'; + expect(map.isNotEmpty, true); + map.remove('01'); + expect(map.isNotEmpty, false); + }); + + test('CanonicalizedMap.length', () { + map.length; + map['1'] = 'value 1'; + map.length; + map['01'] = 'value 01'; + map.length; + map['02'] = 'value 02'; + map.length; + }); + + test('CanonicalizedMap.keys', () { + map['001'] = 'value 1'; + map['02'] = 'value 2'; + map.keys; + }); + + test('CanonicalizedMap.forEach', () { + map['001'] = 'value 1'; + map['02'] = 'value 2'; + + var keys = []; + map.forEach((key, value) => keys.add(key)); + expect(keys, ['001', '02']); + }); + + test('CanonicalizedMap.values', () { + map.addAll({ + '1': 'value 1', + '01': 'value 01', + '2': 'value 2', + '03': 'value 03' + }); + + expect(map.values, ['value 01', 'value 2', 'value 03']); + }); + + test('CanonicalizedMap.entries', () { + map.addAll({ + '1': 'value 1', + '01': 'value 01', + '2': 'value 2', + }); + + var entries = map.entries.toList(); + expect(entries[0].key, '01'); + expect(entries[0].value, 'value 01'); + expect(entries[1].key, '2'); + expect(entries[1].value, 'value 2'); + }); + + test('CanonicalizedMap.addEntries', () { + map.addEntries([ + MapEntry('1', 'value 1'), + MapEntry('01', 'value 01'), + MapEntry('2', 'value 2'), + ]); + expect(map, {'01': 'value 01', '2': 'value 2'}); + }); + + test('CanonicalizedMap.cast()', () { + expect(map.cast(), map); + }); + }); + + test('CanonicalizedMap.from', () { + var map = CanonicalizedMap.from( + {'1': 'value 1', '2': 'value 2', '3': 'value 3'}, int.parse); + expect(map['01'], ('value 1')); + expect(map['02'], ('value 2')); + expect(map['03'], ('value 3')); + + map = CanonicalizedMap.from( + {'1': 'value 1', '01': 'value 2', '001': 'value 3'}, int.parse); + expect(map.length, (1)); + expect(map['0001'], ('value 3')); + }); + } +} diff --git a/ohos/test_collection/lib/page/comparators_test.dart b/ohos/test_collection/lib/page/comparators_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3160821f8d4813252f29480ab477638f2b12710b --- /dev/null +++ b/ohos/test_collection/lib/page/comparators_test.dart @@ -0,0 +1,143 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class ComparatorsTestPage extends TestPage { + ComparatorsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + + + List sortedBy(int Function(String, String)? compare) => + strings.toList() + ..shuffle() + ..sort(compare); + + test('String.compareTo', () { + expect(sortedBy(null), strings); + }); + + test('compareAsciiLowerCase', () { + final ls = sortedBy((a, b) { + var delta = a.toLowerCase().compareTo(b.toLowerCase()); + if (delta != 0) return delta; + if (a == b) return 0; + return a.compareTo(b); + }); + expect(sortedBy(compareAsciiLowerCase), sortedBy((a, b) { + var delta = a.toLowerCase().compareTo(b.toLowerCase()); + if (delta != 0) return delta; + if (a == b) return 0; + return a.compareTo(b); + })); + }); + + test('compareAsciiUpperCase', () { + expect(sortedBy(compareAsciiUpperCase), sortedBy((a, b) { + var delta = a.toUpperCase().compareTo(b.toUpperCase()); + if (delta != 0) return delta; + if (a == b) return 0; + return a.compareTo(b); + })); + }); + + // Replace any digit sequence by ("0", value, length) as char codes. + // This will sort alphabetically (by charcode) the way digits sort + // numerically, and the leading 0 means it sorts like a digit + // compared to non-digits. + String replaceNumbers(String string) => + string.replaceAllMapped(RegExp(r'\d+'), (m) { + var digits = m[0]!; + return String.fromCharCodes([0x30, int.parse(digits), digits.length]); + }); + + test('compareNatural', () { + expect(sortedBy(compareNatural), + sortedBy((a, b) => replaceNumbers(a).compareTo(replaceNumbers(b)))); + }); + + test('compareAsciiLowerCaseNatural', () { + expect(sortedBy(compareAsciiLowerCaseNatural), sortedBy((a, b) { + var delta = replaceNumbers(a.toLowerCase()) + .compareTo(replaceNumbers(b.toLowerCase())); + if (delta != 0) return delta; + if (a == b) return 0; + return a.compareTo(b); + })); + }); + + test('compareAsciiUpperCaseNatural', () { + expect(sortedBy(compareAsciiUpperCaseNatural), sortedBy((a, b) { + var delta = replaceNumbers(a.toUpperCase()) + .compareTo(replaceNumbers(b.toUpperCase())); + if (delta != 0) return delta; + if (a == b) return 0; + return a.compareTo(b); + })); + }); + } + + static List get strings => [ + '', + '\x00', + ' ', + '+', + '/', + '0', + '00', + '000', + '001', + '01', + '011', + '1', + '100', + '11', + '110', + '9', + ':', + '=', + '@', + 'A', + 'A0', + 'A000A', + 'A001A', + 'A00A', + 'A01A', + 'A0A', + 'A1A', + 'AA', + 'AAB', + 'AB', + 'Z', + '[', + '_', + '`', + 'a', + 'a0', + 'a000a', + 'a001a', + 'a00a', + 'a01a', + 'a0a', + 'a1a', + 'aa', + 'aab', + 'ab', + 'z', + '{', + '~' + ]; +} \ No newline at end of file diff --git a/ohos/test_collection/lib/page/equality_map_test.dart b/ohos/test_collection/lib/page/equality_map_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..939ff12293c2805d32f8648a26d7c4660f4545fe --- /dev/null +++ b/ohos/test_collection/lib/page/equality_map_test.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + + +class EqualityMapTestPage extends TestPage { + EqualityMapTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('EqualityMap', () { + var map = EqualityMap(const IterableEquality()); + map.isEmpty; + + map[[1, 2, 3]] = 1; + map[[1, 2, 3]]; + + map[[1, 2, 3]] = 2; + map[[1, 2, 3]]; + + map[[2, 3, 4]] = 3; + map[[2, 3, 4]]; + }); + + test('EqualityMap.from()', () { + var map = EqualityMap.from(const IterableEquality(), { + [1, 2, 3]: 1, + [2, 3, 4]: 2, + [1, 2, 3]: 3, + [2, 3, 4]: 4, + [1, 2, 3]: 5, + [1, 2, 3]: 6, + }); + expect(map[[1, 2, 3]]== 1, true); + expect(map[[2, 3, 4]]== 2, true); + }); + } +} \ No newline at end of file diff --git a/ohos/test_collection/lib/page/equality_set_test.dart b/ohos/test_collection/lib/page/equality_set_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..70e43fa5fce8e1de0b6b9c9ee52036d722b437fe --- /dev/null +++ b/ohos/test_collection/lib/page/equality_set_test.dart @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class EqualitySetTestPage extends TestPage { + EqualitySetTestPage(String title, {Key? key}) + : super(title: title, key: key) { + test('EqualitySet.add EqualitySet.contains', () { + var set = EqualitySet(const IterableEquality()); + expect(set.isEmpty, true); + + var list1 = [1, 2, 3]; + expect(set.add(list1), true); + expect(set.contains([1, 2, 3]), true); + expect(set.contains((list1)), true); + + var list2 = [1, 2, 3]; + expect(set.add(list2), false); + expect(set.contains([1, 2, 3]), true); + expect(set.contains((list1)), true); + expect(set.contains((list2)), true); + + var list3 = [2, 3, 4]; + expect(set.add(list3), true); + expect(set.contains((list1)), true); + expect(set.contains((list3)), true); + }); + + test('EqualitySet.from().contains', () { + var list1 = [1, 2, 3]; + var list2 = [2, 3, 4]; + var list3 = [1, 2, 3]; + var list4 = [2, 3, 4]; + var list5 = [1, 2, 3]; + var list6 = [1, 2, 3]; + + var set = EqualitySet.from( + const IterableEquality(), [list1, list2, list3, list4, list5, list6]); + + expect(set.contains((list1)), true); + expect(set.contains((list2)), true); + expect(set.contains((list3)), true); + expect(set.contains((list4)), true); + expect(set.contains((list5)), true); + expect(set.contains((list6)), true); + }); + } +} diff --git a/ohos/test_collection/lib/page/equality_test.dart b/ohos/test_collection/lib/page/equality_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8ad7649e7a1f620f8937c6451d72e7fa59e54cb5 --- /dev/null +++ b/ohos/test_collection/lib/page/equality_test.dart @@ -0,0 +1,297 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Tests equality utilities. + +import 'dart:collection'; + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class EqualityTestPage extends TestPage { + EqualityTestPage(String title, {Key? key}) : super(title: title, key: key) { + Element o(Comparable id) => Element(id); + + // Lists that are point-wise equal, but not identical. + var list1 = [o(1), o(2), o(3), o(4), o(5)]; + var list2 = [o(1), o(2), o(3), o(4), o(5)]; + // Similar length list with equal elements in different order. + var list3 = [o(1), o(3), o(5), o(4), o(2)]; + + test('IterableEquality.equals', () { + expect(const IterableEquality().equals(list1, list2), true); + Equality iterId = const IterableEquality(IdentityEquality()); + expect(iterId.equals(list1, list2), false); + }); + + test('LinkedHashSet.from().equals', () { + var l1 = LinkedHashSet.from(list1); + var l2 = LinkedHashSet.from(list2); + expect(const IterableEquality().equals(l1, l2), true); + Equality iterId = const IterableEquality(IdentityEquality()); + expect(iterId.equals(l1, l2), false); + }); + + test('ListEquality.equals', () { + expect(const ListEquality().equals(list1, list2), true); + Equality listId = const ListEquality(IdentityEquality()); + expect(listId.equals(list1, list2), false); + }); + + test('ListInequality length', () { + var list4 = [o(1), o(2), o(3), o(4), o(5), o(6)]; + expect(const ListEquality().equals(list1, list4), false); + expect( + const ListEquality(IdentityEquality()).equals(list1, list4), false); + }); + + test('ListInequality value', () { + var list5 = [o(1), o(2), o(3), o(4), o(6)]; + expect(const ListEquality().equals(list1, list5), false); + expect( + const ListEquality(IdentityEquality()).equals(list1, list5), false); + }); + + test('UnorderedIterableEquality.equals', () { + expect(const UnorderedIterableEquality().equals(list1, list3), true); + Equality uniterId = const UnorderedIterableEquality(IdentityEquality()); + expect(uniterId.equals(list1, list3), false); + }); + + test('UnorderedIterableInequality length', () { + var list6 = [o(1), o(3), o(5), o(4), o(2), o(1)]; + expect(const UnorderedIterableEquality().equals(list1, list6), false); + expect( + const UnorderedIterableEquality(IdentityEquality()) + .equals(list1, list6), + false); + }); + + test('UnorderedIterableInequality values', () { + var list7 = [o(1), o(3), o(5), o(4), o(6)]; + expect(const UnorderedIterableEquality().equals(list1, list7), false); + expect( + const UnorderedIterableEquality(IdentityEquality()) + .equals(list1, list7), + false); + }); + + test('SetEquality', () { + var set1 = HashSet.from(list1); + var set2 = LinkedHashSet.from(list3); + expect(const SetEquality().equals(set1, set2), true); + Equality setId = const SetEquality(IdentityEquality()); + expect(setId.equals(set1, set2), false); + }); + + test('SetInequality length', () { + var list8 = [o(1), o(3), o(5), o(4), o(2), o(6)]; + var set1 = HashSet.from(list1); + var set2 = LinkedHashSet.from(list8); + expect(const SetEquality().equals(set1, set2), false); + expect(const SetEquality(IdentityEquality()).equals(set1, set2), false); + }); + + test('SetInequality value', () { + var list7 = [o(1), o(3), o(5), o(4), o(6)]; + var set1 = HashSet.from(list1); + var set2 = LinkedHashSet.from(list7); + expect(const SetEquality().equals(set1, set2), false); + expect(const SetEquality(IdentityEquality()).equals(set1, set2), false); + }); + + var map1a = { + 'x': [o(1), o(2), o(3)], + 'y': [true, false, null] + }; + var map1b = { + 'x': [o(4), o(5), o(6)], + 'y': [false, true, null] + }; + var map2a = { + 'x': [o(3), o(2), o(1)], + 'y': [false, true, null] + }; + var map2b = { + 'x': [o(6), o(5), o(4)], + 'y': [null, false, true] + }; + var l1 = [map1a, map1b]; + var l2 = [map2a, map2b]; + var s1 = {...l1}; + var s2 = {map2b, map2a}; + + var i1 = Iterable.generate(l1.length, (i) => l1[i]); + + test('RecursiveEquality', () { + const unordered = UnorderedIterableEquality(); + expect(unordered.equals(map1a['x'], map2a['x']), true); + expect(unordered.equals(map1a['y'], map2a['y']), true); + expect(unordered.equals(map1b['x'], map2b['x']), true); + expect(unordered.equals(map1b['y'], map2b['y']), true); + const mapval = MapEquality(values: unordered); + expect(mapval.equals(map1a, map2a), true); + expect(mapval.equals(map1b, map2b), true); + const listmapval = ListEquality(mapval); + expect(listmapval.equals(l1, l2), true); + const setmapval = SetEquality(mapval); + expect(setmapval.equals(s1, s2), true); + }); + + test('DeepCollectionEquality.unordered', () { + var colleq = const DeepCollectionEquality.unordered(); + + + expect(colleq.equals(map1a['x'], map2a['x']), true); + expect(colleq.equals(map1a['y'], map2a['y']), true); + expect(colleq.equals(map1b['x'], map2b['x']), true); + expect(colleq.equals(map1b['y'], map2b['y']), true); + expect(colleq.equals(map1a, map2a), true); + expect(colleq.equals(map1b, map2b), true); + expect(colleq.equals(l1, l2), true); + expect(colleq.equals(s1, s2), true); + + + + expect(colleq.equals(l1, i1), false); + expect(colleq.equals(i1, l1), false); + expect(colleq.equals(s1, i1), false); + expect(colleq.equals(i1, s1), true); + + }); + + test('DeepCollectionEquality', () { + var colleq = const DeepCollectionEquality(); + + test('with identical collection types', () { + expect(colleq.equals(l1, l1.toList()), true); + expect(colleq.equals(s1, s1.toSet()), true); + expect(colleq.equals(map1b, map1b), true); + expect(colleq.equals(i1, i1.map((i) => i)), true); + expect(colleq.equals(map1a, map2a), false); + expect(colleq.equals(map1b, map2b), false); + expect(colleq.equals(l1, l2), false); + expect(colleq.equals(s1, s2), false); + }); + + test('comparing collections and iterables', () { + expect(colleq.equals(l1, i1), false); + expect(colleq.equals(i1, l1), true); + expect(colleq.equals(s1, i1), false); + expect(colleq.equals(i1, s1), true); + }); + }); + + + test('CaseInsensitiveEquality', () { + var equality = const CaseInsensitiveEquality(); + expect(equality.equals('foo', 'foo'), true); + expect(equality.equals('fOo', 'FoO'), true); + expect(equality.equals('FoO', 'fOo'), true); + expect(equality.equals('foo', 'bar'), false); + expect(equality.equals('fÕÕ', 'fõõ'), false); + + expect(equality.hash('foo'), (equality.hash('foo'))); + expect(equality.hash('fOo'), (equality.hash('FoO'))); + expect(equality.hash('FoO'), (equality.hash('fOo'))); + expect(equality.hash('foo'), ((equality.hash('bar')))); + expect(equality.hash('fÕÕ'), ((equality.hash('fõõ')))); + }); + + group('EqualityBy should use a derived value for ', () { + var firstEquality = EqualityBy, String>((e) => e.first); + var firstInsensitiveEquality = EqualityBy, String>( + (e) => e.first, const CaseInsensitiveEquality()); + var firstObjectEquality = EqualityBy, Object>( + (e) => e.first, const IterableEquality()); + + test('equality', () { + expect(firstEquality.equals(['foo', 'foo'], ['foo', 'bar']), true); + expect(firstEquality.equals(['foo', 'foo'], ['bar', 'bar']), false); + }); + + test('equality with an inner equality', () { + expect(firstInsensitiveEquality.equals(['fOo'], ['FoO']), true); + expect(firstInsensitiveEquality.equals(['foo'], ['ffõõ']), false); + }); + + test('hash', () { + expect(firstEquality.hash(['foo', 'bar']), 'foo'.hashCode); + }); + + test('hash with an inner equality', () { + expect(firstInsensitiveEquality.hash(['fOo']), + const CaseInsensitiveEquality().hash('foo')); + }); + + test('isValidKey', () { + expect(firstEquality.isValidKey(['foo']), true); + expect(firstEquality.isValidKey('foo'), false); + expect(firstEquality.isValidKey([1]), false); + }); + + test('isValidKey with an inner equality', () { + expect(firstObjectEquality.isValidKey([[]]), true); + expect(firstObjectEquality.isValidKey([{}]), false); + }); + }); + + test('Equality accepts null', () { + var ie = IterableEquality(); + var le = ListEquality(); + var se = SetEquality(); + var me = MapEquality(); + expect(ie.equals(null, null), true); + expect(ie.equals([], null), false); + expect(ie.equals(null, []), false); + expect(ie.hash(null), null.hashCode); + + expect(le.equals(null, null), true); + expect(le.equals([], null), false); + expect(le.equals(null, []), false); + expect(le.hash(null), null.hashCode); + + expect(se.equals(null, null), true); + expect(se.equals({}, null), false); + expect(se.equals(null, {}), false); + expect(se.hash(null), null.hashCode); + + expect(me.equals(null, null), true); + expect(me.equals({}, null), false); + expect(me.equals(null, {}), false); + expect(me.hash(null), null.hashCode); + }); + } +} + +/// Wrapper objects for an `id` value. +/// +/// Compares the `id` value by equality and for comparison. +/// Allows creating simple objects that are equal without being identical. +class Element implements Comparable { + final Comparable id; + + const Element(this.id); + + @override + int get hashCode => id.hashCode; + + @override + bool operator ==(Object other) => other is Element && id == other.id; + + @override + int compareTo(Element other) => id.compareTo(other.id); +} diff --git a/ohos/test_collection/lib/page/functions_test.dart b/ohos/test_collection/lib/page/functions_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3bbe65fed6929e6b332d2c2b74d1ca2bb61de35d --- /dev/null +++ b/ohos/test_collection/lib/page/functions_test.dart @@ -0,0 +1,324 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class FunctionsTestPage extends TestPage { + FunctionsTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('mapMap()', () { + test('mapMap({},key: (_, __) {},value: (_, __) {})', () { + expect( + // ignore: deprecated_member_use_from_same_package + mapMap({}, key: (_, __) {}, value: (_, __) {}), + null); + }); + + test("mapMap({'foo': 1, 'bar': 2})['foo'] = 3", () { + var map = {'foo': 1, 'bar': 2}; + // ignore: deprecated_member_use_from_same_package + var result = mapMap(map); + expect(result, ({'foo': 1, 'bar': 2})); + + // The resulting map should be a copy. + result['foo'] = 3; + expect(map, ({'foo': 1, 'bar': 2})); + }); + + test("mapMap.keys", () { + expect( + // ignore: deprecated_member_use_from_same_package + mapMap({'foo': 1, 'bar': 2}, + key: (dynamic key, dynamic value) => key[value]), + ({'o': 1, 'r': 2})); + }); + + test("mapMap.values", () { + expect( + mapMap({'foo': 1, 'bar': 2}, + value: (dynamic key, dynamic value) => key[value]), + ({'foo': 'o', 'bar': 'r'})); + }); + + test("maps both the map's keys and values", () { + expect( + // ignore: deprecated_member_use_from_same_package + mapMap({'foo': 1, 'bar': 2}, + key: (dynamic key, dynamic value) => '$key$value', + value: (dynamic key, dynamic value) => key[value]), + ({'foo1': 'o', 'bar2': 'r'})); + }); + }); + + group('mergeMaps()', () { + test('mergeMaps({}, {},value: (dynamic _, dynamic __) {})', () { + expect(mergeMaps({}, {}, value: (dynamic _, dynamic __) {}), null); + }); + + test("mergeMaps({'foo': 1, 'bar': 2}, {'baz': 3, 'qux': 4})", () { + expect(mergeMaps({'foo': 1, 'bar': 2}, {'baz': 3, 'qux': 4}), + ({'foo': 1, 'bar': 2, 'baz': 3, 'qux': 4})); + }); + }); + + group('lastBy()', () { + test("lastBy([], (_) => fail('Must not be called for empty input'))", () { + expect( + lastBy([], (_) => fail('Must not be called for empty input')), + null, + ); + }); + + test( + "lastBy(['foo', 'bar', 'baz', 'bop', 'qux'],(String string) => string[1])", + () { + expect( + lastBy(['foo', 'bar', 'baz', 'bop', 'qux'], + (String string) => string[1]), + ({ + 'o': 'bop', + 'a': 'baz', + 'u': 'qux', + })); + }); + }); + + group('groupBy()', () { + test('groupBy([], (dynamic _) {})', () { + expect(groupBy([], (dynamic _) {}), null); + }); + + test( + "groupBy(['foo', 'bar', 'baz', 'bop', 'qux'],(dynamic string) => string[1])", + () { + expect( + groupBy(['foo', 'bar', 'baz', 'bop', 'qux'], + (dynamic string) => string[1]), + ({ + 'o': ['foo', 'bop'], + 'a': ['bar', 'baz'], + 'u': ['qux'] + })); + }); + }); + + group('minBy()', () { + test('minBy([], (dynamic _) {}, compare: (dynamic _, dynamic __) => -1)', + () { + expect( + minBy([], (dynamic _) {}, compare: (dynamic _, dynamic __) => -1), + null); + }); + + test( + "minBy([{'foo': 3},{'foo': 5}, {'foo': 4}, {'foo': 1}, {'foo': 2}], (dynamic map) => map['foo'])", + () { + expect( + minBy([ + {'foo': 3}, + {'foo': 5}, + {'foo': 4}, + {'foo': 1}, + {'foo': 2} + ], (dynamic map) => map['foo']), + ({'foo': 1})); + }); + }); + + group('maxBy()', () { + test('maxBy([], (dynamic _) {}, compare: (dynamic _, dynamic __) => 0)', () { + expect(maxBy([], (dynamic _) {}, compare: (dynamic _, dynamic __) => 0), + null); + }); + }); + + group('transitiveClosure()', () { + test('returns an empty map for an empty graph', () { + expect(transitiveClosure({}), null); + }); + + test('returns the input when there are no transitive connections', () { + expect( + transitiveClosure({ + 'foo': ['bar'], + 'bar': [], + 'bang': ['qux', 'zap'], + 'qux': [], + 'zap': [] + }), + ({ + 'foo': ['bar'], + 'bar': [], + 'bang': ['qux', 'zap'], + 'qux': [], + 'zap': [] + })); + }); + + test('flattens transitive connections', () { + expect( + transitiveClosure({ + 'qux': [], + 'bar': ['baz'], + 'baz': ['qux'], + 'foo': ['bar'] + }), + ({ + 'foo': ['bar', 'baz', 'qux'], + 'bar': ['baz', 'qux'], + 'baz': ['qux'], + 'qux': [] + })); + }); + + test('handles loops', () { + expect( + transitiveClosure({ + 'foo': ['bar'], + 'bar': ['baz'], + 'baz': ['foo'] + }), + ({ + 'foo': ['bar', 'baz', 'foo'], + 'bar': ['baz', 'foo', 'bar'], + 'baz': ['foo', 'bar', 'baz'] + })); + }); + }); + + group('stronglyConnectedComponents()', () { + test('returns an empty list for an empty graph', () { + expect(stronglyConnectedComponents({}), null); + }); + + test('returns one set for a singleton graph', () { + expect( + stronglyConnectedComponents({'a': []}), + ([ + {'a'} + ])); + }); + + test('returns two sets for a two-element tree', () { + expect( + stronglyConnectedComponents({ + 'a': ['b'], + 'b': [] + }), + ([ + {'a'}, + {'b'} + ])); + }); + + test('returns one set for a two-element loop', () { + expect( + stronglyConnectedComponents({ + 'a': ['b'], + 'b': ['a'] + }), + ([ + {'a', 'b'} + ])); + }); + + test('returns individual vertices for a tree', () { + expect( + stronglyConnectedComponents({ + 'foo': ['bar'], + 'bar': ['baz', 'bang'], + 'baz': ['qux'], + 'bang': ['zap'], + 'qux': [], + 'zap': [] + }), + ([ + // This is expected to return *a* topological ordering, but this isn't + // the only valid one. If the function implementation changes in the + // future, this test may need to be updated. + {'foo'}, + {'bar'}, + {'bang'}, + {'zap'}, + {'baz'}, + {'qux'} + ]), + ); + }); + + test('returns a single set for a fully cyclic graph', () { + expect( + stronglyConnectedComponents({ + 'foo': ['bar'], + 'bar': ['baz'], + 'baz': ['bang'], + 'bang': ['foo'] + }), + ([ + {'foo', 'bar', 'baz', 'bang'} + ])); + }); + + test('returns separate sets for each strongly connected component', () { + // https://en.wikipedia.org/wiki/Strongly_connected_component#/media/File:Scc.png + expect( + stronglyConnectedComponents({ + 'a': ['b'], + 'b': ['c', 'e', 'f'], + 'c': ['d', 'g'], + 'd': ['c', 'h'], + 'e': ['a', 'f'], + 'f': ['g'], + 'g': ['f'], + 'h': ['g', 'd'] + }), + ([ + // This is expected to return *a* topological ordering, but this isn't + // the only valid one. If the function implementation changes in the + // future, this test may need to be updated. + {'a', 'b', 'e'}, + {'c', 'd', 'h'}, + {'f', 'g'}, + ]), + ); + }); + + test('always returns components in topological order', () { + expect( + stronglyConnectedComponents({ + 'bar': ['baz', 'bang'], + 'zap': [], + 'baz': ['qux'], + 'qux': [], + 'foo': ['bar'], + 'bang': ['zap'] + }), + ([ + // This is expected to return *a* topological ordering, but this isn't + // the only valid one. If the function implementation changes in the + // future, this test may need to be updated. + {'foo'}, + {'bar'}, + {'bang'}, + {'zap'}, + {'baz'}, + {'qux'} + ]), + ); + }); + }); + } +} diff --git a/ohos/test_collection/lib/page/ignore_ascii_case_test.dart b/ohos/test_collection/lib/page/ignore_ascii_case_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..00f0708bb5c8c49203452523d59e7c67ee432e52 --- /dev/null +++ b/ohos/test_collection/lib/page/ignore_ascii_case_test.dart @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/// Tests case-ignoring compare and equality. + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class IgnoreAsciiCaseTestPage extends TestPage { + IgnoreAsciiCaseTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('equality ignore ASCII case', () { + var strings = [ + '0@`aopz[{', + '0@`aopz[{', + '0@`Aopz[{', + '0@`aOpz[{', + '0@`AOpz[{', + '0@`aoPz[{', + '0@`AoPz[{', + '0@`aOPz[{', + '0@`AOPz[{', + '0@`aopZ[{', + '0@`AopZ[{', + '0@`aOpZ[{', + '0@`AOpZ[{', + '0@`aoPZ[{', + '0@`AoPZ[{', + '0@`aOPZ[{', + '0@`AOPZ[{', + ]; + + for (var s1 in strings) { + for (var s2 in strings) { + var reason = '$s1 =?= $s2'; + expect(equalsIgnoreAsciiCase(s1, s2), true); + expect(hashIgnoreAsciiCase(s1), hashIgnoreAsciiCase(s2), + ); + } + } + + var upperCaseLetters = '@`abcdefghijklmnopqrstuvwxyz[{åÅ'; + var lowerCaseLetters = '@`ABCDEFGHIJKLMNOPQRSTUVWXYZ[{åÅ'; + expect(equalsIgnoreAsciiCase(upperCaseLetters, lowerCaseLetters), true); + + void testChars(String char1, String char2, bool areEqual) { + expect(equalsIgnoreAsciiCase(char1, char2), areEqual + ); + } + + for (var i = 0; i < upperCaseLetters.length; i++) { + for (var j = 0; i < upperCaseLetters.length; i++) { + testChars(upperCaseLetters[i], upperCaseLetters[j], i == j); + testChars(lowerCaseLetters[i], upperCaseLetters[j], i == j); + testChars(upperCaseLetters[i], lowerCaseLetters[j], i == j); + testChars(lowerCaseLetters[i], lowerCaseLetters[j], i == j); + } + } + }); + } +} \ No newline at end of file diff --git a/ohos/test_collection/lib/page/iterable_test_page.dart b/ohos/test_collection/lib/page/iterable_test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..c9babcff71db23bffb78252f8e9eb9d5082004e4 --- /dev/null +++ b/ohos/test_collection/lib/page/iterable_test_page.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +class CombinedIterableViewTestPage extends TestPage { + CombinedIterableViewTestPage(String title,{ Key? key}) : super(title: title, key: key) { + var iterable1 = Iterable.generate(3); + var iterable2 = Iterable.generate(3, (i) => i + 3); + var iterable3 = Iterable.generate(3, (i) => i + 6); + + test('CombinedIterableView()', () { + var combined = CombinedIterableView([iterable1, iterable2, iterable3]); + expect(combined, [0, 1, 2, 3, 4, 5, 6, 7, 8]); + + combined = CombinedIterableView([iterable1, [], iterable2, [], iterable3, []]); + expect(combined, [0, 1, 2, 3, 4, 5, 6, 7, 8]); + }); + + test('CombinedIterableView().isEmpty', () { + var empty = CombinedIterableView([]); + empty.isEmpty; + + empty = CombinedIterableView([[], [], []]); + expect(empty, null); + }); + + test('CombinedIterableView.last CombinedIterableView.first', () { + var list1 = []; + var list2 = []; + var combined = CombinedIterableView([list1, list2]); + expect(combined, null); + list1.addAll([1, 2]); + list2.addAll([3, 4]); + expect(combined, [1, 2, 3, 4]); + expect(combined.last, 4); + expect(combined.first, 1); + }); + } +} diff --git a/ohos/test_collection/lib/page/iterable_zip_test.dart b/ohos/test_collection/lib/page/iterable_zip_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..533bbc638ed888902e8c52ade4089e012db41b05 --- /dev/null +++ b/ohos/test_collection/lib/page/iterable_zip_test.dart @@ -0,0 +1,192 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +/// Iterable like [base] except that it throws when value [errorValue]. +Iterable iterError(Iterable base, int errorValue) { + // ignore: only_throw_errors + return base.map((x) => x == errorValue ? throw 'BAD' : x); +} + +class IterableZipTestPage extends TestPage { + IterableZipTestPage(String title, {Key? key}) + : super(title: title, key: key) { + test('IterableZip()', () { + expect( + IterableZip([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9] + ]), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + + expect( + IterableZip([ + [1, 2, 3, 99, 100], + [4, 5, 6], + [7, 8, 9] + ]), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + + expect( + IterableZip([ + [1, 2, 3], + [4, 5, 6, 99, 100], + [7, 8, 9] + ]), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + + expect( + IterableZip([ + [1, 2, 3], + [4, 5, 6], + [7, 8, 9, 99, 100] + ]), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + + expect( + IterableZip([ + [1, 2, 3, 98], + [4, 5, 6], + [7, 8, 9, 99, 100] + ]), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + + expect( + IterableZip([ + [], + [4, 5, 6], + [7, 8, 9] + ]), + ([])); + + expect( + IterableZip([ + [1, 2, 3], + [], + [7, 8, 9] + ]), + ([])); + + expect( + IterableZip([ + [1, 2, 3], + [4, 5, 6], + [] + ]), + ([])); + + expect(IterableZip([]), ([])); + + expect( + IterableZip([ + [1, 2, 3] + ]), + ([ + [1], + [2], + [3] + ])); + }); + + test('复杂构造IterableZip', () { + // Use other iterables than list literals. + var it1 = [1, 2, 3, 4, 5, 6].where((x) => x < 4); + var it2 = {4, 5, 6}; + var it3 = {7: 0, 8: 0, 9: 0}.keys; + var allIts = Iterable.generate(3, (i) => [it1, it2, it3][i]); + expect( + IterableZip(allIts), + ([ + [1, 4, 7], + [2, 5, 8], + [3, 6, 9] + ])); + }); + + test('Error 1', () { + expect( + IterableZip([ + iterError([1, 2, 3], 2), + [4, 5, 6], + [7, 8, 9] + ]).toList(), + ('BAD')); + }); + + test('Error 2', () { + expect( + IterableZip([ + [1, 2, 3], + iterError([4, 5, 6], 5), + [7, 8, 9] + ]).toList(), + ('BAD')); + }); + + test('Error 3', () { + expect( + IterableZip([ + [1, 2, 3], + [4, 5, 6], + iterError([7, 8, 9], 8) + ]).toList(), + (('BAD'))); + }); + + test('Error at end', () { + expect( + IterableZip([ + [1, 2, 3], + iterError([4, 5, 6], 6), + [7, 8, 9] + ]).toList(), + (('BAD'))); + }); + + test('Error before first end', () { + expect( + IterableZip([ + iterError([1, 2, 3, 4], 4), + [4, 5, 6], + [7, 8, 9] + ]).toList(), + (('BAD'))); + }); + } +} diff --git a/ohos/test_collection/lib/page/list_test.dart b/ohos/test_collection/lib/page/list_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..283115afc128703b512a4f493234d56abebbf8c7 --- /dev/null +++ b/ohos/test_collection/lib/page/list_test.dart @@ -0,0 +1,618 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class CombinedListViewTestPage extends TestPage { + CombinedListViewTestPage(String title,{ Key? key}) : super(title: title, key: key) { + var list1 = [1, 2, 3]; + var list2 = [4, 5, 6]; + var list3 = [7, 8, 9]; + var concat = [...list1, ...list2, ...list3]; + + // In every way possible this should test the same as an UnmodifiableListView. + testUnmodifiableList(concat, CombinedListView([list1, list2, list3]), 'combineLists'); + + testUnmodifiableList(concat, CombinedListView([list1, [], list2, [], list3, []]), 'combineLists'); + + test('CombinedListView().length', () { + var empty = CombinedListView([]); + expect(empty, null); + expect(empty.length, 0); + + empty = CombinedListView([[], [], []]); + expect(empty, null); + expect(empty.length, 0); + + }); + + test('CombinedListView([],[])', () { + var backing1 = []; + var backing2 = []; + var combined = CombinedListView([backing1, backing2]); + expect(combined, null); + backing1.addAll(list1); + expect(combined, list1); + backing2.addAll(list2); + expect(combined, backing1.toList()..addAll(backing2)); + var listOfLists = >[]; + combined = CombinedListView(listOfLists); + expect(combined, null); + listOfLists.add(list1); + expect(combined, list1); + listOfLists.add(list2); + expect(combined, [...list1, ...list2]); + listOfLists.clear(); + expect(combined, null); + backing1 = []; + combined = CombinedListView([backing1]); + expect(combined, null); + backing1.addAll(list1); + expect(combined, list1); + }); + } + + void testUnmodifiableList(List original, List wrapped, String name) { + name = 'unmodifiable-list-$name'; + testIterable(original, wrapped, name); + testReadList(original, wrapped, name); + testNoWriteList(original, wrapped, name); + testNoChangeLengthList(original, wrapped, name); + } + + void testNonGrowableList(List original, List wrapped, String name) { + name = 'nongrowable-list-$name'; + testIterable(original, wrapped, name); + testReadList(original, wrapped, name); + testWriteList(original, wrapped, name); + testNoChangeLengthList(original, wrapped, name); + } + + void testUnmodifiableSet(Set original, Set wrapped, String name) { + name = 'unmodifiable-set-$name'; + testIterable(original, wrapped, name); + testReadSet(original, wrapped, name); + testNoChangeSet(original, wrapped, name); + } + + void testIterable(Iterable original, Iterable wrapped, String name) { + test('$name - any', () { + expect(wrapped.any((x) => true), (original.any((x) => true))); + expect(wrapped.any((x) => false), (original.any((x) => false))); + }); + + test('$name - contains', () { + expect(wrapped.contains(0), (original.contains(0))); + }); + + test('$name - elementAt', () { + if (original.isEmpty) { + wrapped.elementAt(0); + } else { + expect(wrapped.elementAt(0), (original.elementAt(0))); + } + }); + + test('$name - every', () { + expect(wrapped.every((x) => true), (original.every((x) => true))); + expect(wrapped.every((x) => false), (original.every((x) => false))); + }); + + test('$name - expand', () { + expect(wrapped.expand((x) => [x, x]), (original.expand((x) => [x, x]))); + }); + + test('$name - first', () { + if (original.isEmpty) { + wrapped.first; + } else { + expect(wrapped.first, (original.first)); + } + }); + + test('$name - firstWhere', () { + if (original.isEmpty) { + wrapped.firstWhere((_) => true); + } else { + expect(wrapped.firstWhere((_) => true), (original.firstWhere((_) => true))); + } + }); + + test('$name - fold', () { + expect(wrapped.fold(0, (dynamic x, y) => x + y), (original.fold(0, (dynamic x, y) => x + y))); + }); + + test('$name - forEach', () { + var wrapCtr = 0; + var origCtr = 0; + // ignore: avoid_function_literals_in_foreach_calls + wrapped.forEach((x) { + wrapCtr += x; + }); + // ignore: avoid_function_literals_in_foreach_calls + original.forEach((x) { + origCtr += x; + }); + expect(wrapCtr, (origCtr)); + }); + + test('$name - isEmpty', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name - isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name - iterator', () { + Iterator wrapIter = wrapped.iterator; + Iterator origIter = original.iterator; + while (origIter.moveNext()) { + expect(wrapIter.moveNext(), (true)); + expect(wrapIter.current, (origIter.current)); + } + expect(wrapIter.moveNext(), (false)); + }); + + test('$name - join', () { + expect(wrapped.join(''), (original.join(''))); + expect(wrapped.join('-'), (original.join('-'))); + }); + + test('$name - last', () { + if (original.isEmpty) { + wrapped.last; + } else { + expect(wrapped.last, (original.last)); + } + }); + + test('$name - lastWhere', () { + if (original.isEmpty) { + wrapped.lastWhere((_) => true); + } else { + expect(wrapped.lastWhere((_) => true), (original.lastWhere((_) => true))); + } + }); + + test('$name - length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name - map', () { + expect(wrapped.map((x) => '[$x]'), (original.map((x) => '[$x]'))); + }); + + test('$name - reduce', () { + if (original.isEmpty) { + wrapped.reduce((x, y) => x + y); + } else { + expect(wrapped.reduce((x, y) => x + y), (original.reduce((x, y) => x + y))); + } + }); + + test('$name - single', () { + if (original.length == 1) { + expect(wrapped.single, (original.single)); + } + }); + + test('$name - singleWhere', () { + if (original.length == 1) { + expect(wrapped.singleWhere((_) => true), (original.singleWhere((_) => true))); + } + }); + + test('$name - skip', () { + expect(wrapped.skip(0), (original.skip(0))); + expect(wrapped.skip(1), (original.skip(1))); + expect(wrapped.skip(5), (original.skip(5))); + }); + + test('$name - skipWhile', () { + expect(wrapped.skipWhile((x) => true), (original.skipWhile((x) => true))); + expect(wrapped.skipWhile((x) => false), (original.skipWhile((x) => false))); + expect(wrapped.skipWhile((x) => x != 42), (original.skipWhile((x) => x != 42))); + }); + + test('$name - take', () { + expect(wrapped.take(0), (original.take(0))); + expect(wrapped.take(1), (original.take(1))); + expect(wrapped.take(5), (original.take(5))); + }); + + test('$name - takeWhile', () { + expect(wrapped.takeWhile((x) => true), (original.takeWhile((x) => true))); + expect(wrapped.takeWhile((x) => false), (original.takeWhile((x) => false))); + expect(wrapped.takeWhile((x) => x != 42), (original.takeWhile((x) => x != 42))); + }); + + test('$name - toList', () { + expect(wrapped.toList(), (original.toList())); + expect(wrapped.toList(growable: false), (original.toList(growable: false))); + }); + + test('$name - toSet', () { + expect(wrapped.toSet(), (original.toSet())); + }); + + test('$name - where', () { + expect(wrapped.where((x) => true), (original.where((x) => true))); + expect(wrapped.where((x) => false), (original.where((x) => false))); + expect(wrapped.where((x) => x != 42), (original.where((x) => x != 42))); + }); + } + + void testReadList(List original, List wrapped, String name) { + test('$name - length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name - isEmpty', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name - isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name - []', () { + if (original.isEmpty) { + + wrapped[0]; + + } else { + expect(wrapped[0], (original[0])); + } + }); + + test('$name - indexOf', () { + expect(wrapped.indexOf(42), (original.indexOf(42))); + }); + + test('$name - lastIndexOf', () { + expect(wrapped.lastIndexOf(42), (original.lastIndexOf(42))); + }); + + test('$name - getRange', () { + var len = original.length; + expect(wrapped.getRange(0, len), (original.getRange(0, len))); + expect(wrapped.getRange(len ~/ 2, len), (original.getRange(len ~/ 2, len))); + expect(wrapped.getRange(0, len ~/ 2), (original.getRange(0, len ~/ 2))); + }); + + test('$name - sublist', () { + var len = original.length; + expect(wrapped.sublist(0), (original.sublist(0))); + expect(wrapped.sublist(len ~/ 2), (original.sublist(len ~/ 2))); + expect(wrapped.sublist(0, len ~/ 2), (original.sublist(0, len ~/ 2))); + }); + + test('$name - asMap', () { + expect(wrapped.asMap(), (original.asMap())); + }); + } + + void testNoWriteList(List original, List wrapped, String name) { + var copy = List.of(original); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name - []= throws', () { + wrapped[0] = 42; + }); + + testThrows('$name - sort throws', () { + wrapped.sort(); + }); + + testThrows('$name - fillRange throws', () { + wrapped.fillRange(0, wrapped.length, 42); + }); + + testThrows('$name - setRange throws', () { + wrapped.setRange(0, wrapped.length, Iterable.generate(wrapped.length, (i) => i)); + }); + + testThrows('$name - setAll throws', () { + wrapped.setAll(0, Iterable.generate(wrapped.length, (i) => i)); + }); + } + + void testWriteList(List original, List wrapped, String name) { + var copy = List.of(original); + + test('$name - []=', () { + if (original.isNotEmpty) { + var originalFirst = original[0]; + wrapped[0] = originalFirst + 1; + expect(original[0], (originalFirst + 1)); + original[0] = originalFirst; + } else { + + wrapped[0] = 42; + + } + }); + + test('$name - sort', () { + var sortCopy = List.of(original); + sortCopy.sort(); + wrapped.sort(); + expect(original, (sortCopy)); + original.setAll(0, copy); + }); + + test('$name - fillRange', () { + wrapped.fillRange(0, wrapped.length, 37); + for (var i = 0; i < original.length; i++) { + expect(original[i], (37)); + } + original.setAll(0, copy); + }); + + test('$name - setRange', () { + List reverseList = original.reversed.toList(); + wrapped.setRange(0, wrapped.length, reverseList); + expect(original, (reverseList)); + original.setAll(0, copy); + }); + + test('$name - setAll', () { + List reverseList = original.reversed.toList(); + wrapped.setAll(0, reverseList); + expect(original, (reverseList)); + original.setAll(0, copy); + }); + } + + void testNoChangeLengthList(List original, List wrapped, String name) { + var copy = List.of(original); + + void testThrows(String name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name - length= throws', () { + wrapped.length = 100; + }); + + testThrows('$name - add throws', () { + wrapped.add(42); + }); + + testThrows('$name - addAll throws', () { + wrapped.addAll([42]); + }); + + testThrows('$name - insert throws', () { + wrapped.insert(0, 42); + }); + + testThrows('$name - insertAll throws', () { + wrapped.insertAll(0, [42]); + }); + + testThrows('$name - remove throws', () { + wrapped.remove(42); + }); + + testThrows('$name - removeAt throws', () { + wrapped.removeAt(0); + }); + + testThrows('$name - removeLast throws', () { + wrapped.removeLast(); + }); + + testThrows('$name - removeWhere throws', () { + wrapped.removeWhere((element) => false); + }); + + testThrows('$name - retainWhere throws', () { + wrapped.retainWhere((element) => true); + }); + + testThrows('$name - removeRange throws', () { + wrapped.removeRange(0, wrapped.length); + }); + + testThrows('$name - replaceRange throws', () { + wrapped.replaceRange(0, wrapped.length, [42]); + }); + + testThrows('$name - clear throws', () { + wrapped.clear(); + }); + } + + void testReadSet(Set original, Set wrapped, String name) { + var copy = Set.of(original); + + test('$name - containsAll', () { + expect(wrapped.containsAll(copy), true); + expect(wrapped.containsAll(copy.toList()), true); + expect(wrapped.containsAll([]), true); + expect(wrapped.containsAll([42]), (original.containsAll([42]))); + }); + + test('$name - intersection', () { + expect(wrapped.intersection({}), null); + expect(wrapped.intersection(copy), (original)); + expect(wrapped.intersection({42}), Set.of(original.contains(42) ? [42] : [])); + }); + + test('$name - union', () { + expect(wrapped.union({}), (original)); + expect(wrapped.union(copy), (original)); + expect(wrapped.union({42}), (original.union({42}))); + }); + + test('$name - difference', () { + expect(wrapped.difference({}), (original)); + expect(wrapped.difference(copy), null); + expect(wrapped.difference({42}), (original.difference({42}))); + }); + } + + void testNoChangeSet(Set original, Set wrapped, String name) { + var originalElements = original.toList(); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original.toList(), (originalElements)); + }); + } + + testThrows('$name - add throws', () { + wrapped.add(42); + }); + + testThrows('$name - addAll throws', () { + wrapped.addAll([42]); + }); + + testThrows('$name - addAll empty throws', () { + wrapped.addAll([]); + }); + + testThrows('$name - remove throws', () { + wrapped.remove(42); + }); + + testThrows('$name - removeAll throws', () { + wrapped.removeAll([42]); + }); + + testThrows('$name - removeAll empty throws', () { + wrapped.removeAll([]); + }); + + testThrows('$name - retainAll throws', () { + wrapped.retainAll([42]); + }); + + testThrows('$name - removeWhere throws', () { + wrapped.removeWhere((_) => false); + }); + + testThrows('$name - retainWhere throws', () { + wrapped.retainWhere((_) => true); + }); + + testThrows('$name - clear throws', () { + wrapped.clear(); + }); + } + + void testReadMap(Map original, Map wrapped, String name) { + test('$name length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name isEmpty', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name operator[]', () { + expect(wrapped[0], (0)); + expect(wrapped[999], (999)); + }); + + test('$name containsKey', () { + expect(wrapped.containsKey(0), (original.containsKey(0))); + expect(wrapped.containsKey(999), (original.containsKey(999))); + }); + + test('$name containsValue', () { + expect(wrapped.containsValue(0), (original.containsValue(0))); + expect(wrapped.containsValue(999), (original.containsValue(999))); + }); + + test('$name forEach', () { + var origCnt = 0; + var wrapCnt = 0; + wrapped.forEach((k, v) { + wrapCnt += 1 << k + 3 * v; + }); + original.forEach((k, v) { + origCnt += 1 << k + 3 * v; + }); + expect(wrapCnt, (origCnt)); + }); + + test('$name keys', () { + expect(wrapped.keys, (original.keys)); + }); + + test('$name values', () { + expect(wrapped.values, (original.values)); + }); + } + + void testNoChangeMap(Map original, Map wrapped, String name) { + var copy = Map.of(original); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name operator[]= throws', () { + wrapped[0] = 42; + }); + + testThrows('$name putIfAbsent throws', () { + wrapped.putIfAbsent(0, () => 42); + }); + + testThrows('$name addAll throws', () { + wrapped.addAll({42: 42}); + }); + + testThrows('$name addAll empty throws', () { + wrapped.addAll({}); + }); + + testThrows('$name remove throws', () { + wrapped.remove(0); + }); + + testThrows('$name clear throws', () { + wrapped.clear(); + }); + } +} diff --git a/ohos/test_collection/lib/page/map_test.dart b/ohos/test_collection/lib/page/map_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..305638f6842cc925587c3522afe537ac02f518b1 --- /dev/null +++ b/ohos/test_collection/lib/page/map_test.dart @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:collection'; +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class CombinedMapViewTestPage extends TestPage { + CombinedMapViewTestPage(String title, {Key? key}) + : super(title: title, key: key) { + var map1 = const {1: 1, 2: 2, 3: 3}; + var map2 = const {4: 4, 5: 5, 6: 6}; + var map3 = const {7: 7, 8: 8, 9: 9}; + var map4 = const {1: -1, 2: -2, 3: -3}; + var concat = SplayTreeMap() + // The duplicates map appears first here but last in the CombinedMapView + // which has the opposite semantics of `concat`. Keys/values should be + // returned from the first map that contains them. + ..addAll(map4) + ..addAll(map1) + ..addAll(map2) + ..addAll(map3); + + // In every way possible this should test the same as an UnmodifiableMapView. + testReadMap( + concat, CombinedMapView([map1, map2, map3, map4]), 'CombinedMapView'); + + testReadMap( + concat, + CombinedMapView([map1, {}, map2, {}, map3, {}, map4, {}]), + 'CombinedMapView (some empty)'); + + test('CombinedMapView().length', () { + var empty = CombinedMapView([]); + expect(empty, null); + expect(empty.length, 0); + + empty = CombinedMapView([{}, {}, {}]); + expect(empty, null); + expect(empty.length, 0); + }); + + test('CombinedMapView合并map', () { + var backing1 = {}; + var backing2 = {}; + var combined = CombinedMapView([backing1, backing2]); + expect(combined, null); + backing1.addAll(map1); + expect(combined, map1); + backing2.addAll(map2); + expect(combined, Map.from(backing1)..addAll(backing2)); + backing1 = {}; + combined = CombinedMapView([backing1]); + expect(combined, null); + backing1.addAll(map1); + expect(combined, map1); + }); + + test('CombinedMapView.keys', () { + var combined = CombinedMapView([map1, map2, map3, map4]); + var keys = combined.keys; + expect(keys.toList(), keys.toList()); + }); + } + + void testReadMap(Map original, Map wrapped, String name) { + test('$name length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name null', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name operator[]', () { + expect(wrapped[0], (0)); + expect(wrapped[999], (999)); + }); + + test('$name containsKey', () { + expect(wrapped.containsKey(0), (original.containsKey(0))); + expect(wrapped.containsKey(999), (original.containsKey(999))); + }); + + test('$name containsValue', () { + expect(wrapped.containsValue(0), (original.containsValue(0))); + expect(wrapped.containsValue(999), (original.containsValue(999))); + }); + + test('$name forEach', () { + var origCnt = 0; + var wrapCnt = 0; + wrapped.forEach((k, v) { + wrapCnt += 1 << k + 3 * v; + }); + original.forEach((k, v) { + origCnt += 1 << k + 3 * v; + }); + expect(wrapCnt, (origCnt)); + }); + + test('$name keys', () { + expect(wrapped.keys, (original.keys)); + }); + + test('$name values', () { + expect(wrapped.values, (original.values)); + }); + } +} diff --git a/ohos/test_collection/lib/page/mirrors.dart b/ohos/test_collection/lib/page/mirrors.dart new file mode 100644 index 0000000000000000000000000000000000000000..8f3dd0832167d80def96b3abc1c91b784725fcad --- /dev/null +++ b/ohos/test_collection/lib/page/mirrors.dart @@ -0,0 +1,1201 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// For the purposes of the mirrors library, we adopt a naming +// convention with respect to getters and setters. Specifically, for +// some variable or field... +// +// var myField; +// +// ...the getter is named 'myField' and the setter is named +// 'myField='. This allows us to assign unique names to getters and +// setters for the purposes of member lookup. + +/** + * Basic reflection in Dart, + * with support for introspection and dynamic invocation. + * + * *Introspection* is that subset of reflection by which a running + * program can examine its own structure. For example, a function + * that prints out the names of all the members of an arbitrary object. + * + * *Dynamic invocation* refers the ability to evaluate code that + * has not been literally specified at compile time, such as calling a method + * whose name is provided as an argument (because it is looked up + * in a database, or provided interactively by the user). + * + * ## How to interpret this library's documentation + * + * As a rule, the names of Dart declarations are represented using + * instances of class [Symbol]. Whenever the doc speaks of an object *s* + * of class [Symbol] denoting a name, it means the string that + * was used to construct *s*. + * + * The documentation frequently abuses notation with + * Dart pseudo-code such as [:o.x(a):], where + * o and a are defined to be objects; what is actually meant in these + * cases is [:o'.x(a'):] where *o'* and *a'* are Dart variables + * bound to *o* and *a* respectively. Furthermore, *o'* and *a'* + * are assumed to be fresh variables (meaning that they are + * distinct from any other variables in the program). + * + * Sometimes the documentation refers to *serializable* objects. + * An object is serializable across isolates if and only if it is an instance of + * num, bool, String, a list of objects that are serializable + * across isolates, or a map with keys and values that are all serializable across + * isolates. + * + * ## Status: Unstable + * + * The dart:mirrors library is unstable and its API might change slightly as a + * result of user feedback. This library is only supported by the Dart VM and + * only available on some platforms. + * + * {@category VM} + */ +library dart.mirrors; + +import "dart:core"; + +// TODO: Move AbstractClassInstantiationError here when removed from dart:core. +export "dart:core" show AbstractClassInstantiationError; + +/** + * A [MirrorSystem] is the main interface used to reflect on a set of + * associated libraries. + * + * At runtime each running isolate has a distinct [MirrorSystem]. + * + * It is also possible to have a [MirrorSystem] which represents a set + * of libraries which are not running -- perhaps at compile-time. In + * this case, all available reflective functionality would be + * supported, but runtime functionality (such as invoking a function + * or inspecting the contents of a variable) would fail dynamically. + */ +abstract class MirrorSystem { + /** + * All libraries known to the mirror system, indexed by their URI. + * + * Returns an unmodifiable map of the libraries with [LibraryMirror.uri] as + * keys. + * + * For a runtime mirror system, only libraries which are currently loaded + * are included, and repeated calls of this method may return different maps + * as libraries are loaded. + */ + Map get libraries; + + /** + * Returns the unique library named [libraryName] if it exists. + * + * If no unique library exists, an error is thrown. + */ + external LibraryMirror findLibrary(Symbol libraryName); + + /** + * A mirror on the isolate associated with this [MirrorSystem]. + * + * This may be null if this mirror system is not running. + */ + IsolateMirror get isolate; + + /** + * A mirror on the [:dynamic:] type. + */ + TypeMirror get dynamicType; + + /** + * A mirror on the [:void:] type. + */ + TypeMirror get voidType; + + /** + * A mirror on the [:Never:] type. + */ + TypeMirror get neverType; + + /** + * Returns the name of [symbol]. + */ + external static String getName(Symbol symbol); + + /** + * Returns a symbol for [name]. + * + * If [library] is not a [LibraryMirror] or if [name] is a private identifier + * and [library] is `null`, throws an [ArgumentError]. If [name] is a private + * identifier, the symbol returned is with respect to [library]. + * + * The following text is non-normative: + * + * Using this method may result in larger output. If possible, use + * the const constructor of [Symbol] or symbol literals. + */ + external static Symbol getSymbol(String name, [LibraryMirror? library]); +} + +/** + * Returns a [MirrorSystem] for the current isolate. + */ +external MirrorSystem currentMirrorSystem(); + +/** + * Reflects an instance. + * + * Returns an [InstanceMirror] reflecting [reflectee]. If [reflectee] is a + * function or an instance of a class that has a [:call:] method, the returned + * instance mirror will be a [ClosureMirror]. + * + * Note that since one cannot obtain an object from another isolate, this + * function can only be used to obtain mirrors on objects of the current + * isolate. + */ +external InstanceMirror reflect(dynamic reflectee); + +/** + * Reflects a class declaration. + * + * Let *C* be the original class declaration of the class represented by [key]. + * This function returns a [ClassMirror] reflecting *C*. + * + * If [key] is not an instance of [Type], then this function throws an + * [ArgumentError]. If [key] is the Type for dynamic or a function typedef, + * throws an [ArgumentError]. + * + * Note that since one cannot obtain a [Type] object from another isolate, this + * function can only be used to obtain class mirrors on classes of the current + * isolate. + */ +external ClassMirror reflectClass(Type key); + +/** + * Reflects the type represented by [key]. + * + * If [key] is not an instance of [Type], then this function throws an + * [ArgumentError]. + * + * Optionally takes a list of [typeArguments] for generic classes. If the list + * is provided, then the [key] must be a generic class type, and the number of + * the provided type arguments must be equal to the number of type variables + * declared by the class. + * + * Note that since one cannot obtain a [Type] object from another isolate, this + * function can only be used to obtain type mirrors on types of the current + * isolate. + */ +external TypeMirror reflectType(Type key, [List? typeArguments]); + +/** + * A [Mirror] reflects some Dart language entity. + * + * Every [Mirror] originates from some [MirrorSystem]. + */ +abstract class Mirror {} + +/** + * An [IsolateMirror] reflects an isolate. + */ +abstract class IsolateMirror implements Mirror { + /** + * A unique name used to refer to the isolate in debugging messages. + */ + String get debugName; + + /** + * Whether this mirror reflects the currently running isolate. + */ + bool get isCurrent; + + /** + * The root library for the reflected isolate. + */ + LibraryMirror get rootLibrary; + + /** + * Whether [other] is an [IsolateMirror] on the same isolate as this mirror. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. the isolate being reflected by this mirror is the same isolate being + * reflected by [other]. + */ + bool operator ==(Object other); + + /** + * Loads the library at the given uri into this isolate. + * + * WARNING: You are strongly encouraged to use Isolate.spawnUri instead when + * possible. IsolateMirror.loadUri should only be used when synchronous + * communication or shared state with dynamically loaded code is needed. + * + * If a library with the same canonicalized uri has already been loaded, + * the existing library will be returned. (The isolate will not load a new + * copy of the library.) + * + * This behavior is similar to the behavior of an import statement that + * appears in the root library, except that the import scope of the root + * library is not changed. + */ + Future loadUri(Uri uri); +} + +/** + * A [DeclarationMirror] reflects some entity declared in a Dart program. + */ +abstract class DeclarationMirror implements Mirror { + /** + * The simple name for this Dart language entity. + * + * The simple name is in most cases the identifier name of the entity, + * such as 'myMethod' for a method, [:void myMethod() {...}:] or 'mylibrary' + * for a [:library 'mylibrary';:] declaration. + */ + Symbol get simpleName; + + /** + * The fully-qualified name for this Dart language entity. + * + * This name is qualified by the name of the owner. For instance, + * the qualified name of a method 'method' in class 'Class' in + * library 'library' is 'library.Class.method'. + * + * Returns a [Symbol] constructed from a string representing the + * fully qualified name of the reflectee. + * Let *o* be the [owner] of this mirror, let *r* be the reflectee of + * this mirror, let *p* be the fully qualified + * name of the reflectee of *o*, and let *s* be the simple name of *r* + * computed by [simpleName]. + * The fully qualified name of *r* is the + * concatenation of *p*, '.', and *s*. + * + * Because an isolate can contain more than one library with the same name (at + * different URIs), a fully-qualified name does not uniquely identify any + * language entity. + */ + Symbol get qualifiedName; + + /** + * A mirror on the owner of this Dart language entity. + * + * The owner is the declaration immediately surrounding the reflectee: + * + * * For a library, the owner is [:null:]. + * * For a class declaration, typedef or top level function or variable, the + * owner is the enclosing library. + * * For a mixin application `S with M`, the owner is the owner of `M`. + * * For a constructor, the owner is the immediately enclosing class. + * * For a method, instance variable or a static variable, the owner is the + * immediately enclosing class, unless the class is a mixin application + * `S with M`, in which case the owner is `M`. Note that `M` may be an + * invocation of a generic. + * * For a parameter, local variable or local function the owner is the + * immediately enclosing function. + */ + DeclarationMirror? get owner; + + /** + * Whether this declaration is library private. + * + * Always returns `false` for a library declaration, + * otherwise returns `true` if the declaration's name starts with an + * underscore character (`_`), and `false` if it doesn't. + */ + bool get isPrivate; + + /** + * Whether this declaration is top-level. + * + * A declaration is considered top-level if its [owner] is a [LibraryMirror]. + */ + bool get isTopLevel; + + /** + * The source location of this Dart language entity, or [:null:] if the + * entity is synthetic. + * + * If the reflectee is a variable, the returned location gives the position + * of the variable name at its point of declaration. + * + * If the reflectee is a library, class, typedef, function or type variable + * with associated metadata, the returned location gives the position of the + * first metadata declaration associated with the reflectee. + * + * Otherwise: + * + * If the reflectee is a library, the returned location gives the position of + * the keyword 'library' at the reflectee's point of declaration, if the + * reflectee is a named library, or the first character of the first line in + * the compilation unit defining the reflectee if the reflectee is anonymous. + * + * If the reflectee is an abstract class, the returned location gives the + * position of the keyword 'abstract' at the reflectee's point of declaration. + * Otherwise, if the reflectee is a class, the returned location gives the + * position of the keyword 'class' at the reflectee's point of declaration. + * + * If the reflectee is a typedef the returned location gives the position of + * the of the keyword 'typedef' at the reflectee's point of declaration. + * + * If the reflectee is a function with a declared return type, the returned + * location gives the position of the function's return type at the + * reflectee's point of declaration. Otherwise. the returned location gives + * the position of the function's name at the reflectee's point of + * declaration. + * + * This operation is optional and may throw an [UnsupportedError]. + */ + SourceLocation? get location; + + /** + * A list of the metadata associated with this declaration. + * + * Let *D* be the declaration this mirror reflects. + * If *D* is decorated with annotations *A1, ..., An* + * where *n > 0*, then for each annotation *Ai* associated + * with *D, 1 <= i <= n*, let *ci* be the constant object + * specified by *Ai*. Then this method returns a list whose + * members are instance mirrors on *c1, ..., cn*. + * If no annotations are associated with *D*, then + * an empty list is returned. + * + * If evaluating any of *c1, ..., cn* would cause a + * compilation error + * the effect is the same as if a non-reflective compilation error + * had been encountered. + */ + List get metadata; +} + +/** + * An [ObjectMirror] is a common superinterface of [InstanceMirror], + * [ClassMirror], and [LibraryMirror] that represents their shared + * functionality. + * + * For the purposes of the mirrors library, these types are all + * object-like, in that they support method invocation and field + * access. Real Dart objects are represented by the [InstanceMirror] + * type. + * + * See [InstanceMirror], [ClassMirror], and [LibraryMirror]. + */ +abstract class ObjectMirror implements Mirror { + /** + * Invokes the named function and returns a mirror on the result. + * + * Let *o* be the object reflected by this mirror, let *f* be the simple name + * of the member denoted by [memberName], let *a1, ..., an* be the elements + * of [positionalArguments], let *k1, ..., km* be the identifiers denoted by + * the elements of [namedArguments].keys, and let *v1, ..., vm* be the + * elements of [namedArguments].values. Then this method will perform the + * method invocation *o.f(a1, ..., an, k1: v1, ..., km: vm)* in a scope that + * has access to the private members of *o* (if *o* is a class or library) or + * the private members of the class of *o* (otherwise). + * + * If the invocation returns a result *r*, this method returns the result of + * calling [reflect]\(*r*\). + * + * If the invocation causes a compilation error the effect is the same as if + * a non-reflective compilation error had been encountered. + * + * If the invocation throws an exception *e* (that it does not catch), this + * method throws *e*. + */ + InstanceMirror invoke(Symbol memberName, List positionalArguments, + [Map namedArguments = const {}]); + + /** + * Invokes a getter and returns a mirror on the result. + * + * The getter can be the implicit getter for a field or a user-defined getter + * method. + * + * Let *o* be the object reflected by this mirror, + * let *f* be the simple name of the getter denoted by [fieldName]. + * + * Then this method will perform the getter invocation *o.f* in a scope that + * has access to the private members of *o* (if *o* is a class or library) or + * the private members of the class of *o* (otherwise). + * + * If this mirror is an [InstanceMirror], and [fieldName] denotes an instance + * method on its reflectee, the result of the invocation is an instance + * mirror on a closure corresponding to that method. + * + * If this mirror is a [LibraryMirror], and [fieldName] denotes a top-level + * method in the corresponding library, the result of the invocation is an + * instance mirror on a closure corresponding to that method. + * + * If this mirror is a [ClassMirror], and [fieldName] denotes a static method + * in the corresponding class, the result of the invocation is an instance + * mirror on a closure corresponding to that method. + * + * If the invocation returns a result *r*, this method returns the result of + * calling [reflect]\(*r*\). + * + * If the invocation causes a compilation error, the effect is the same as if + * a non-reflective compilation error had been encountered. + * + * If the invocation throws an exception *e* (that it does not catch), this + * method throws *e*. + */ + // TODO(ahe): Remove stuff about scope and private members. [fieldName] is a + // capability giving access to private members. + InstanceMirror getField(Symbol fieldName); + + /** + * Invokes a setter and returns a mirror on the result. + * + * The setter may be either the implicit setter for a non-final field or a + * user-defined setter method. + * + * Let *o* be the object reflected by this mirror, + * let *f* be the simple name of the getter denoted by [fieldName], + * and let *a* be the object bound to [value]. + * + * Then this method will perform the setter invocation *o.f = a* in a scope + * that has access to the private members of *o* (if *o* is a class or + * library) or the private members of the class of *o* (otherwise). + * + * If the invocation returns a result *r*, this method returns the result of + * calling [reflect]\([value]\). + * + * If the invocation causes a compilation error, the effect is the same as if + * a non-reflective compilation error had been encountered. + * + * If the invocation throws an exception *e* (that it does not catch) this + * method throws *e*. + */ + InstanceMirror setField(Symbol fieldName, dynamic value); + + /** + * Performs [invocation] on the reflectee of this [ObjectMirror]. + * + * Equivalent to + * + * if (invocation.isGetter) { + * return this.getField(invocation.memberName).reflectee; + * } else if (invocation.isSetter) { + * return this.setField(invocation.memberName, + * invocation.positionalArguments[0]).reflectee; + * } else { + * return this.invoke(invocation.memberName, + * invocation.positionalArguments, + * invocation.namedArguments).reflectee; + * } + */ + delegate(Invocation invocation); +} + +/** + * An [InstanceMirror] reflects an instance of a Dart language object. + */ +abstract class InstanceMirror implements ObjectMirror { + /** + * A mirror on the type of the reflectee. + * + * Returns a mirror on the actual class of the reflectee. + * The class of the reflectee may differ from + * the object returned by invoking [runtimeType] on + * the reflectee. + */ + ClassMirror get type; + + /** + * Whether [reflectee] will return the instance reflected by this mirror. + * + * This will always be true in the local case (reflecting instances in the + * same isolate), but only true in the remote case if this mirror reflects a + * simple value. + * + * A value is simple if one of the following holds: + * + * * the value is [:null:] + * * the value is of type [num] + * * the value is of type [bool] + * * the value is of type [String] + */ + bool get hasReflectee; + + /** + * If the [InstanceMirror] reflects an instance it is meaningful to + * have a local reference to, we provide access to the actual + * instance here. + * + * If you access [reflectee] when [hasReflectee] is false, an + * exception is thrown. + */ + dynamic get reflectee; + + /** + * Whether this mirror is equal to [other]. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. either + * + * a. [hasReflectee] is true and so is + * [:identical(reflectee, other.reflectee):], or + * + * b. the remote objects reflected by this mirror and by [other] are + * identical. + */ + bool operator ==(Object other); +} + +/** + * A [ClosureMirror] reflects a closure. + * + * A [ClosureMirror] provides the ability to execute its reflectee and + * introspect its function. + */ +abstract class ClosureMirror implements InstanceMirror { + /** + * A mirror on the function associated with this closure. + * + * The function associated with an implicit closure of a function is that + * function. + * + * The function associated with an instance of a class that has a [:call:] + * method is that [:call:] method. + * + * A Dart implementation might choose to create a class for each closure + * expression, in which case [:function:] would be the same as + * [:type.declarations[#call]:]. But the Dart language model does not require + * this. A more typical implementation involves a single closure class for + * each type signature, where the call method dispatches to a function held + * in the closure rather the call method + * directly implementing the closure body. So one cannot rely on closures from + * distinct closure expressions having distinct classes ([:type:]), but one + * can rely on them having distinct functions ([:function:]). + */ + MethodMirror get function; + + /** + * Executes the closure and returns a mirror on the result. + * + * Let *f* be the closure reflected by this mirror, + * let *a1, ..., an* be the elements of [positionalArguments], + * let *k1, ..., km* be the identifiers denoted by the elements of + * [namedArguments].keys, + * and let *v1, ..., vm* be the elements of [namedArguments].values. + * + * Then this method will perform the method invocation + * *f(a1, ..., an, k1: v1, ..., km: vm)*. + * + * If the invocation returns a result *r*, this method returns the result of + * calling [reflect]\(*r*\). + * + * If the invocation causes a compilation error, the effect is the same as if + * a non-reflective compilation error had been encountered. + * + * If the invocation throws an exception *e* (that it does not catch), this + * method throws *e*. + */ + InstanceMirror apply(List positionalArguments, + [Map namedArguments = const {}]); +} + +/** + * A [LibraryMirror] reflects a Dart language library, providing + * access to the variables, functions, and classes of the + * library. + */ +abstract class LibraryMirror implements DeclarationMirror, ObjectMirror { + /** + * The absolute uri of the library. + */ + Uri get uri; + + /** + * Returns an immutable map of the declarations actually given in the library. + * + * This map includes all regular methods, getters, setters, fields, classes + * and typedefs actually declared in the library. The map is keyed by the + * simple names of the declarations. + */ + Map get declarations; + + /** + * Whether this mirror is equal to [other]. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. The library being reflected by this mirror and the library being + * reflected by [other] are the same library in the same isolate. + */ + bool operator ==(Object other); + + /** + * Returns a list of the imports and exports in this library; + */ + List get libraryDependencies; +} + +/// A mirror on an import or export declaration. +abstract class LibraryDependencyMirror implements Mirror { + /// Is `true` if this dependency is an import. + bool get isImport; + + /// Is `true` if this dependency is an export. + bool get isExport; + + /// Returns true iff this dependency is a deferred import. Otherwise returns + /// false. + bool get isDeferred; + + /// Returns the library mirror of the library that imports or exports the + /// [targetLibrary]. + LibraryMirror get sourceLibrary; + + /// Returns the library mirror of the library that is imported or exported, + /// or null if the library is not loaded. + LibraryMirror? get targetLibrary; + + /// Returns the prefix if this is a prefixed import and `null` otherwise. + Symbol? get prefix; + + /// Returns the list of show/hide combinators on the import/export + /// declaration. + List get combinators; + + /// Returns the source location for this import/export declaration. + SourceLocation? get location; + + List get metadata; + + /// Returns a future that completes with a library mirror on the library being + /// imported or exported when it is loaded, and initiates a load of that + /// library if it is not loaded. + Future loadLibrary(); +} + +/// A mirror on a show/hide combinator declared on a library dependency. +abstract class CombinatorMirror implements Mirror { + /// The list of identifiers on the combinator. + List get identifiers; + + /// Is `true` if this is a 'show' combinator. + bool get isShow; + + /// Is `true` if this is a 'hide' combinator. + bool get isHide; +} + +/** + * A [TypeMirror] reflects a Dart language class, typedef, + * function type or type variable. + */ +abstract class TypeMirror implements DeclarationMirror { + /** + * Returns true if this mirror reflects dynamic, a non-generic class or + * typedef, or an instantiated generic class or typedef in the current + * isolate. Otherwise, returns false. + */ + bool get hasReflectedType; + + /** + * If [:hasReflectedType:] returns true, returns the corresponding [Type]. + * Otherwise, an [UnsupportedError] is thrown. + */ + Type get reflectedType; + + /** + * An immutable list with mirrors for all type variables for this type. + * + * If this type is a generic declaration or an invocation of a generic + * declaration, the returned list contains mirrors on the type variables + * declared in the original declaration. + * Otherwise, the returned list is empty. + * + * This list preserves the order of declaration of the type variables. + */ + List get typeVariables; + + /** + * An immutable list with mirrors for all type arguments for + * this type. + * + * If the reflectee is an invocation of a generic class, + * the type arguments are the bindings of its type parameters. + * If the reflectee is the original declaration of a generic, + * it has no type arguments and this method returns an empty list. + * If the reflectee is not generic, then + * it has no type arguments and this method returns an empty list. + * + * This list preserves the order of declaration of the type variables. + */ + List get typeArguments; + + /** + * Is this the original declaration of this type? + * + * For most classes, they are their own original declaration. For + * generic classes, however, there is a distinction between the + * original class declaration, which has unbound type variables, and + * the instantiations of generic classes, which have bound type + * variables. + */ + bool get isOriginalDeclaration; + + /** + * A mirror on the original declaration of this type. + * + * For most classes, they are their own original declaration. For + * generic classes, however, there is a distinction between the + * original class declaration, which has unbound type variables, and + * the instantiations of generic classes, which have bound type + * variables. + */ + TypeMirror get originalDeclaration; + + /** + * Checks the subtype relationship, denoted by `<:` in the language + * specification. + * + * This is the type relationship used in `is` test checks. + */ + bool isSubtypeOf(TypeMirror other); + + /** + * Checks the assignability relationship, denoted by `<=>` in the language + * specification. + * + * This is the type relationship tested on assignment in checked mode. + */ + bool isAssignableTo(TypeMirror other); +} + +/** + * A [ClassMirror] reflects a Dart language class. + */ +abstract class ClassMirror implements TypeMirror, ObjectMirror { + /** + * A mirror on the superclass on the reflectee. + * + * If this type is [:Object:], the superclass will be null. + */ + ClassMirror? get superclass; + + /** + * A list of mirrors on the superinterfaces of the reflectee. + */ + List get superinterfaces; + + /** + * Is the reflectee abstract? + */ + bool get isAbstract; + + /** + * Is the reflectee an enum? + */ + bool get isEnum; + + /** + * Returns an immutable map of the declarations actually given in the class + * declaration. + * + * This map includes all regular methods, getters, setters, fields, + * constructors and type variables actually declared in the class. Both + * static and instance members are included, but no inherited members are + * included. The map is keyed by the simple names of the declarations. + * + * This does not include inherited members. + */ + Map get declarations; + + /** + * Returns a map of the methods, getters and setters of an instance of the + * class. + * + * The intent is to capture those members that constitute the API of an + * instance. Hence fields are not included, but the getters and setters + * implicitly introduced by fields are included. The map includes methods, + * getters and setters that are inherited as well as those introduced by the + * class itself. + * + * The map is keyed by the simple names of the members. + */ + Map get instanceMembers; + + /** + * Returns a map of the static methods, getters and setters of the class. + * + * The intent is to capture those members that constitute the API of a class. + * Hence fields are not included, but the getters and setters implicitly + * introduced by fields are included. + * + * The map is keyed by the simple names of the members. + */ + Map get staticMembers; + + /** + * The mixin of this class. + * + * If this class is the result of a mixin application of the form S with M, + * returns a class mirror on M. Otherwise returns a class mirror on + * the reflectee. + */ + ClassMirror get mixin; + + /** + * Invokes the named constructor and returns a mirror on the result. + * + * Let *c* be the class reflected by this mirror, + * let *a1, ..., an* be the elements of [positionalArguments], + * let *k1, ..., km* be the identifiers denoted by the elements of + * [namedArguments].keys, + * and let *v1, ..., vm* be the elements of [namedArguments].values. + * + * If [constructorName] was created from the empty string, then this method + * will execute the instance creation expression + * *new c(a1, ..., an, k1: v1, ..., km: vm)* in a scope that has access to + * the private members of *c*. + * + * Otherwise, let *f* be the simple name of the constructor denoted by + * [constructorName]. Then this method will execute the instance creation + * expression *new c.f(a1, ..., an, k1: v1, ..., km: vm)* in a scope that has + * access to the private members of *c*. + * + * In either case: + * + * * If the expression evaluates to a result *r*, this method returns the + * result of calling [reflect]\(*r*\). + * * If evaluating the expression causes a compilation error, the effect is + * the same as if a non-reflective compilation error had been encountered. + * * If evaluating the expression throws an exception *e* (that it does not + * catch), this method throws *e*. + */ + InstanceMirror newInstance( + Symbol constructorName, List positionalArguments, + [Map namedArguments = const {}]); + + /** + * Whether this mirror is equal to [other]. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. This mirror and [other] reflect the same class. + * + * Note that if the reflected class is an invocation of a generic class, 2. + * implies that the reflected class and [other] have equal type arguments. + */ + bool operator ==(Object other); + + /** + * Returns whether the class denoted by the receiver is a subclass of the + * class denoted by the argument. + * + * Note that the subclass relationship is reflexive. + */ + bool isSubclassOf(ClassMirror other); +} + +/** + * A [FunctionTypeMirror] represents the type of a function in the + * Dart language. + */ +abstract class FunctionTypeMirror implements ClassMirror { + /** + * Returns the return type of the reflectee. + */ + TypeMirror get returnType; + + /** + * Returns a list of the parameter types of the reflectee. + */ + List get parameters; + + /** + * A mirror on the [:call:] method for the reflectee. + */ + // This is only here because in the past the VM did not implement a call + // method on closures. + MethodMirror get callMethod; +} + +/** + * A [TypeVariableMirror] represents a type parameter of a generic type. + */ +abstract class TypeVariableMirror extends TypeMirror { + /** + * A mirror on the type that is the upper bound of this type variable. + */ + TypeMirror get upperBound; + + /** + * Is the reflectee static? + * + * For the purposes of the mirrors library, type variables are considered + * non-static. + */ + bool get isStatic; + + /** + * Whether [other] is a [TypeVariableMirror] on the same type variable as this + * mirror. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. + */ + bool operator ==(Object other); +} + +/** + * A [TypedefMirror] represents a typedef in a Dart language program. + */ +abstract class TypedefMirror implements TypeMirror { + /** + * The defining type for this typedef. + * + * If the type referred to by the reflectee is a function type *F*, the + * result will be [:FunctionTypeMirror:] reflecting *F* which is abstract + * and has an abstract method [:call:] whose signature corresponds to *F*. + * For instance [:void f(int):] is the referent for [:typedef void f(int):]. + */ + FunctionTypeMirror get referent; +} + +/** + * A [MethodMirror] reflects a Dart language function, method, + * constructor, getter, or setter. + */ +abstract class MethodMirror implements DeclarationMirror { + /** + * A mirror on the return type for the reflectee. + */ + TypeMirror get returnType; + + /** + * The source code for the reflectee, if available. Otherwise null. + */ + String? get source; + + /** + * A list of mirrors on the parameters for the reflectee. + */ + List get parameters; + + /** + * A function is considered non-static iff it is permited to refer to 'this'. + * + * Note that generative constructors are considered non-static, whereas + * factory constructors are considered static. + */ + bool get isStatic; + + /** + * Is the reflectee abstract? + */ + bool get isAbstract; + + /** + * Returns true if the reflectee is synthetic, and returns false otherwise. + * + * A reflectee is synthetic if it is a getter or setter implicitly introduced + * for a field or Type, or if it is a constructor that was implicitly + * introduced as a default constructor or as part of a mixin application. + */ + bool get isSynthetic; + + /** + * Is the reflectee a regular function or method? + * + * A function or method is regular if it is not a getter, setter, or + * constructor. Note that operators, by this definition, are + * regular methods. + */ + bool get isRegularMethod; + + /** + * Is the reflectee an operator? + */ + bool get isOperator; + + /** + * Is the reflectee a getter? + */ + bool get isGetter; + + /** + * Is the reflectee a setter? + */ + bool get isSetter; + + /** + * Is the reflectee a constructor? + */ + bool get isConstructor; + + /** + * The constructor name for named constructors and factory methods. + * + * For unnamed constructors, this is the empty string. For + * non-constructors, this is the empty string. + * + * For example, [:'bar':] is the constructor name for constructor + * [:Foo.bar:] of type [:Foo:]. + */ + Symbol get constructorName; + + /** + * Is the reflectee a const constructor? + */ + bool get isConstConstructor; + + /** + * Is the reflectee a generative constructor? + */ + bool get isGenerativeConstructor; + + /** + * Is the reflectee a redirecting constructor? + */ + bool get isRedirectingConstructor; + + /** + * Is the reflectee a factory constructor? + */ + bool get isFactoryConstructor; + + /** + * Is the reflectee an extension method? + */ + bool get isExtensionMember; + + /** + * Whether this mirror is equal to [other]. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. + */ + bool operator ==(Object other); +} + +/** + * A [VariableMirror] reflects a Dart language variable declaration. + */ +abstract class VariableMirror implements DeclarationMirror { + /** + * Returns a mirror on the type of the reflectee. + */ + TypeMirror get type; + + /** + * Returns [:true:] if the reflectee is a static variable. + * Otherwise returns [:false:]. + * + * For the purposes of the mirror library, top-level variables are + * implicitly declared static. + */ + bool get isStatic; + + /** + * Returns [:true:] if the reflectee is a final variable. + * Otherwise returns [:false:]. + */ + bool get isFinal; + + /** + * Returns [:true:] if the reflectee is declared [:const:]. + * Otherwise returns [:false:]. + */ + bool get isConst; + + /** + * Is the reflectee an extension member? + */ + bool get isExtensionMember; + + /** + * Whether this mirror is equal to [other]. + * + * The equality holds if and only if + * + * 1. [other] is a mirror of the same kind, and + * 2. [:simpleName == other.simpleName:] and [:owner == other.owner:]. + */ + bool operator ==(Object other); +} + +/** + * A [ParameterMirror] reflects a Dart formal parameter declaration. + */ +abstract class ParameterMirror implements VariableMirror { + /** + * A mirror on the type of this parameter. + */ + TypeMirror get type; + + /** + * Returns [:true:] if the reflectee is an optional parameter. + * Otherwise returns [:false:]. + */ + bool get isOptional; + + /** + * Returns [:true:] if the reflectee is a named parameter. + * Otherwise returns [:false:]. + */ + bool get isNamed; + + /** + * Returns [:true:] if the reflectee has explicitly declared a default value. + * Otherwise returns [:false:]. + */ + bool get hasDefaultValue; + + /** + * Returns the default value of an optional parameter. + * + * Returns an [InstanceMirror] on the (compile-time constant) + * default value for an optional parameter. + * If no default value is declared, it defaults to `null` + * and a mirror of `null` is returned. + * + * Returns `null` for a required parameter. + */ + InstanceMirror? get defaultValue; +} + +/** + * A [SourceLocation] describes the span of an entity in Dart source code. + */ +abstract class SourceLocation { + /** + * The 1-based line number for this source location. + * + * A value of 0 means that the line number is unknown. + */ + int get line; + + /** + * The 1-based column number for this source location. + * + * A value of 0 means that the column number is unknown. + */ + int get column; + + /** + * Returns the URI where the source originated. + */ + Uri get sourceUri; +} diff --git a/ohos/test_collection/lib/page/priority_queue_test.dart b/ohos/test_collection/lib/page/priority_queue_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e2f6068a6d626a9862346d78bc75f28d0d31bcc1 --- /dev/null +++ b/ohos/test_collection/lib/page/priority_queue_test.dart @@ -0,0 +1,389 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/// Tests priority queue implementations utilities. +import 'package:collection/src/priority_queue.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class PriorityQueueTestPage extends TestPage { + PriorityQueueTestPage(String title,{ Key? key}) : super(title: title, key: key) { + testDefault(); + testDuplicates(); + testNullable(); + testConcurrentModification(); + } + + + void testDefault() { + test('PriorityQueue() returns a HeapPriorityQueue', () { + PriorityQueue(); + }); + } + + void testInt(PriorityQueue Function() create) { + for (var count in [1, 5, 127, 128]) { + testQueue('int:$count', create, List.generate(count, (x) => x), count); + } + } + + void testCustom(PriorityQueue Function(int Function(C, C)? comparator) create) { + for (var count in [1, 5, 127, 128]) { + testQueue('Custom:$count/null', () => create(null), + List.generate(count, C as C Function(int index)), C(count)); + testQueue('Custom:$count/compare', () => create(compare), + List.generate(count, C as C Function(int index)), C(count)); + testQueue('Custom:$count/compareNeg', () => create(compareNeg), + List.generate(count, (x) => C(count - x)), C(0)); + } + } + + /// Test that a queue behaves correctly. + /// + /// The elements must be in priority order, from highest to lowest. + void testQueue(String name, + PriorityQueue Function() create, + List elements, + T notElement,) { + test(name, () => testQueueBody(create, elements, notElement)); + } + + void testQueueBody(PriorityQueue Function() create, List elements, T notElement) { + var q = create(); + expect(q.isEmpty, true); + expect(q, 0); + + q.first; + + + q.removeFirst(); + + + // Tests removeFirst, first, contains, toList and toSet. + void testElements() { + expect(q.isNotEmpty, true); + expect(q, elements.length); + + expect(q.toList(), (elements)); + expect(q.toSet().toList(), (elements)); + expect(q.toUnorderedList(), (elements)); + expect(q.unorderedElements, (elements)); + + var allElements = q.removeAll(); + q.addAll(allElements); + + for (var i = 0; i < elements.length; i++) { + expect(q.contains(elements[i]), true); + } + expect(q.contains(notElement), false); + + var all = []; + while (q.isNotEmpty) { + var expected = q.first; + var actual = q.removeFirst(); + expect(actual, expected); + all.add(actual); + } + + expect(all.length, elements.length); + for (var i = 0; i < all.length; i++) { + expect(all[i], elements[i]); + } + + expect(q.isEmpty, true); + } + + q.addAll(elements); + testElements(); + + q.addAll(elements.reversed); + testElements(); + + // Add elements in a non-linear order (gray order). + for (var i = 0, j = 0; i < elements.length; i++) { + int gray; + do { + gray = j ^ (j >> 1); + j++; + } while (gray >= elements.length); + q.add(elements[gray]); + } + testElements(); + + // Add elements by picking the middle element first, and then recursing + // on each side. + void addRec(int min, int max) { + var mid = min + ((max - min) >> 1); + q.add(elements[mid]); + if (mid + 1 < max) addRec(mid + 1, max); + if (mid > min) addRec(min, mid); + } + + addRec(0, elements.length); + testElements(); + + // Test removeAll. + q.addAll(elements); + expect(q, elements.length); + var all = q.removeAll(); + expect(q.isEmpty, true); + expect(all, elements.length); + for (var i = 0; i < elements.length; i++) { + expect(all, elements[i]); + } + + // Test the same element more than once in queue. + q.addAll(elements); + q.addAll(elements.reversed); + expect(q, elements.length * 2); + for (var i = 0; i < elements.length; i++) { + var element = elements[i]; + expect(q.contains(element), true); + expect(q.removeFirst(), element); + expect(q.removeFirst(), element); + } + + // Test queue with all same element. + var a = elements[0]; + for (var i = 0; i < elements.length; i++) { + q.add(a); + } + expect(q, elements.length); + expect(q.contains(a), true); + expect(q.contains(notElement), false); + q.removeAll().forEach((x) => expect(x, a)); + + // Test remove. + q.addAll(elements); + for (var element in elements.reversed) { + expect(q.remove(element), true); + } + expect(q.isEmpty, true); + } + + void testDuplicates() { + // Check how the heap handles duplicate, or equal-but-not-identical, values. + test('HeapPriorityQueue(compare)', () { + var q = HeapPriorityQueue(compare); + var c1 = C(0); + var c2 = C(0); + + // Can contain the same element more than once. + expect(c1, (c2)); + expect(c1, c2); + q.add(c1); + q.add(c1); + expect(q.length, 2); + expect(q.contains(c1), true); + expect(q.contains(c2), true); + expect(q.remove(c2), true); + expect(q.length, 1); + expect(q.removeFirst(), c1); + + // Can contain equal elements. + q.add(c1); + q.add(c2); + expect(q.length, 2); + expect(q.contains(c1), true); + expect(q.contains(c2), true); + expect(q.remove(c1), true); + expect(q.length, 1); + expect(q.first,c1); + }); + } + + void testNullable() { + // Check that the queue works with a nullable type, and a comparator + // which accepts `null`. + // Compares `null` before instances of `C`. + int nullCompareFirst(C? a, C? b) => + a == null + ? b == null + ? 0 + : -1 + : b == null + ? 1 + : compare(a, b); + + int nullCompareLast(C? a, C? b) => + a == null + ? b == null + ? 0 + : 1 + : b == null + ? -1 + : compare(a, b); + + var c1 = C(1); + var c2 = C(2); + var c3 = C(3); + + test('HeapPriorityQueue(nullCompareFirst', () { + var q = HeapPriorityQueue(nullCompareFirst); + q.add(c2); + q.add(c1); + q.add(null); + expect(q.length, 3); + expect(q.contains(null), true); + expect(q.contains(c1), true); + expect(q.contains(c3), false); + + expect(q.removeFirst(), null); + expect(q.length, 2); + expect(q.contains(null), false); + q.add(null); + expect(q.length, 3); + expect(q.contains(null), true); + q.add(null); + expect(q.length, 4); + expect(q.contains(null), true); + expect(q.remove(null), true); + expect(q.length, 3); + expect(q.toList(), [null, c1, c2]); + }); + + test('HeapPriorityQueue(nullCompareLast)', () { + var q = HeapPriorityQueue(nullCompareLast); + q.add(c2); + q.add(c1); + q.add(null); + expect(q.length, 3); + expect(q.contains(null), true); + expect(q.contains(c1), true); + expect(q.contains(c3), false); + expect(q.first, c1); + + q.add(null); + expect(q.length, 4); + expect(q.contains(null), true); + q.add(null); + expect(q.length, 5); + expect(q.contains(null), true); + expect(q.remove(null), true); + expect(q.length, 4); + expect(q.toList(), [c1, c2, null, null]); + }); + } + + void testConcurrentModification() { + group('HeapPriorityQueue 属性', () { + test('add', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + q.add(12); // Modifiation before creating iterator is not a problem. + var it = e.iterator; + q.add(7); // Modification after creatig iterator is a problem. + it.moveNext; + + it = e.iterator; // New iterator is not affected. + expect(it.moveNext(), true); + expect(it.moveNext(), true); + q.add(9); // Modification during iteration is a problem. + it.moveNext; + }); + + test('addAll', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + q.addAll([12]); // Modifiation before creating iterator is not a problem. + var it = e.iterator; + q.addAll([7]); // Modification after creatig iterator is a problem. + it.moveNext; + it = e.iterator; // New iterator is not affected. + expect(it.moveNext(), true); + q.addAll([]); // Adding nothing is not a modification. + expect(it.moveNext(), true); + q.addAll([9]); // Modification during iteration is a problem. + it.moveNext; + }); + + test('removeFirst', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + expect(q.removeFirst(), + 2); // Modifiation before creating iterator is not a problem. + var it = e.iterator; + expect(q.removeFirst(), + 3); // Modification after creatig iterator is a problem. + it.moveNext; + + it = e.iterator; // New iterator is not affected. + expect(it.moveNext(), true); + expect(it.moveNext(), true); + expect(q.removeFirst(), 4); // Modification during iteration is a problem. + it.moveNext; + }); + + test('remove', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + expect(q.remove(3), true); + var it = e.iterator; + expect(q.remove(2), true); + it.moveNext; + it = e.iterator; + expect(q.remove(99), false); + expect(it.moveNext(), true); + expect(it.moveNext(), true); + expect(q.remove(5), true); + it.moveNext; + }); + + test('removeAll', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + var it = e.iterator; + expect(it.moveNext(), true); + expect(it.moveNext(),true); + expect(q.removeAll(), 6); + it.moveNext; + }); + + test('clear', () { + var q = HeapPriorityQueue((a, b) => a - b) + ..addAll([6, 4, 2, 3, 5, 8]); + var e = q.unorderedElements; + var it = e.iterator; + expect(it.moveNext(), true); + expect(it.moveNext(), true); + q.clear(); + it.moveNext; + }); + }); + } + +// Custom class. +// Class is comparable, comparators match normal and inverse order. + int compare(C c1, C c2) => c1.value - c2.value; + + int compareNeg(C c1, C c2) => c2.value - c1.value; +} +class C implements Comparable { + final int value; + const C(this.value); + @override + int get hashCode => value; + @override + bool operator ==(Object other) => other is C && value == other.value; + @override + int compareTo(C other) => value - other.value; + @override + String toString() => 'C($value)'; +} diff --git a/ohos/test_collection/lib/page/queue_list_test.dart b/ohos/test_collection/lib/page/queue_list_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3a72719d0926a59ffb2d3b0ceaa49084cc14e84d --- /dev/null +++ b/ohos/test_collection/lib/page/queue_list_test.dart @@ -0,0 +1,272 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class QueueListTestPage extends TestPage { + QueueListTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('QueueList()', () { + test('QueueList().isEmpty', () { + expect(QueueList().isEmpty, QueueList().isEmpty); + }); + + test('QueueList(100).isEmpty', () { + expect(QueueList(100).isEmpty, QueueList(100).isEmpty); + }); + }); + + test('QueueList.from() copies the contents of an iterable', () { + expect(QueueList.from([1, 2, 3].skip(1)), ([2, 3])); + }); + + test('QueueList.add()', () { + var queue = QueueList.from([1, 2, 3]); + queue.add(4); + expect(queue, ([1, 2, 3, 4])); + + var queue1 = atCapacity(); + queue1.add(8); + expect(queue1, ([1, 2, 3, 4, 5, 6, 7, 8])); + }); + + test('QueueList.addAll()', () { + var queue = QueueList.from([1, 2, 3]); + queue.addAll([4, 5, 6]); + expect(queue, ([1, 2, 3, 4, 5, 6])); + + var queue1 = atCapacity(); + queue1.addAll([8, 9]); + expect(queue1, ([1, 2, 3, 4, 5, 6, 7, 8, 9])); + }); + + test('QueueList.addFirst()', () { + var queue = QueueList.from([1, 2, 3]); + queue.addFirst(0); + expect(queue, ([0, 1, 2, 3])); + + var queue1 = atCapacity(); + queue1.addFirst(0); + expect(queue1, ([0, 1, 2, 3, 4, 5, 6, 7])); + }); + + test('QueueList.removeFirst()', () { + var queue = QueueList.from([1, 2, 3]); + expect(queue.removeFirst(), (1)); + expect(queue, ([2, 3])); + + var queue1 = withInternalGap(); + expect(queue1.removeFirst(), (1)); + expect(queue1, ([2, 3, 4, 5, 6, 7])); + + var queue2 = atCapacity(); + expect(queue2.removeFirst(), (1)); + expect(queue2, ([2, 3, 4, 5, 6, 7])); + + QueueList().removeFirst; + }); + + group('QueueList.removeLast()', () { + var queue = QueueList.from([1, 2, 3]); + expect(queue.removeLast(), (3)); + expect(queue, ([1, 2])); + + var queue1 = withInternalGap(); + expect(queue1.removeLast(), (7)); + expect(queue1, ([1, 2, 3, 4, 5, 6])); + + var queue2 = atCapacity(); + expect(queue2.removeLast(), (7)); + expect(queue2, ([1, 2, 3, 4, 5, 6])); + + QueueList().removeLast; + }); + + group('QueueList.length', () { + expect(QueueList.from([1, 2, 3]).length, (3)); + + expect(withInternalGap().length, (7)); + + expect(atCapacity().length, (7)); + + var queue = QueueList.from([1, 2, 3]); + queue.length = 1; + expect(queue, ([1])); + + var queue1 = QueueList.from([1, 2, 3]); + queue1.length = 5; + expect(queue1, ([1, 2, 3, null, null])); + }); + test('QueueList().length = -1 throws a RangeError', () { + QueueList().length = -1; + }); + + test('QueueList().length = 1 throws an UnsupportedError', () { + QueueList().length = 1; + }); + + group('[]', () { + test('QueueList.from([1, 2, 3])', () { + var queue = QueueList.from([1, 2, 3]); + expect(queue[0], (1)); + expect(queue[1], (2)); + expect(queue[2], (3)); + }); + + test('returns individual entries in a queue with an internal gap', () { + var queue = withInternalGap(); + expect(queue[0], (1)); + expect(queue[1], (2)); + expect(queue[2], (3)); + expect(queue[3], (4)); + expect(queue[4], (5)); + expect(queue[5], (6)); + expect(queue[6], (7)); + }); + + test('throws a RangeError if the index is less than 0', () { + var queue = QueueList.from([1, 2, 3]); + queue[-1]; + }); + + test( + 'throws a RangeError if the index is greater than or equal to the ' + 'length', () { + var queue = QueueList.from([1, 2, 3]); + queue[3]; + }); + }); + + group('[]=', () { + test('sets individual entries in the queue', () { + var queue = QueueList.from([1, 2, 3]); + queue[0] = 'a'; + queue[1] = 'b'; + queue[2] = 'c'; + expect(queue, (['a', 'b', 'c'])); + }); + + test('sets individual entries in a queue with an internal gap', () { + var queue = withInternalGap(); + queue[0] = 'a'; + queue[1] = 'b'; + queue[2] = 'c'; + queue[3] = 'd'; + queue[4] = 'e'; + queue[5] = 'f'; + queue[6] = 'g'; + expect(queue, (['a', 'b', 'c', 'd', 'e', 'f', 'g'])); + }); + + test('throws a RangeError if the index is less than 0', () { + var queue = QueueList.from([1, 2, 3]); + + queue[-1] = 0; + }); + + test( + 'throws a RangeError if the index is greater than or equal to the ' + 'length', () { + var queue = QueueList.from([1, 2, 3]); + + queue[3] = 4; + }); + }); + + group('throws a modification error for', () { + dynamic queue; + // setUp(() { + queue = QueueList.from([1, 2, 3]); + // }); + + test('add', () { + expect(() => queue.forEach((_) => queue.add(4)), + throwsConcurrentModificationError); + }); + + test('addAll', () { + expect(() => queue.forEach((_) => queue.addAll([4, 5, 6])), + throwsConcurrentModificationError); + }); + + test('addFirst', () { + expect(() => queue.forEach((_) => queue.addFirst(0)), + throwsConcurrentModificationError); + }); + + test('removeFirst', () { + expect(() => queue.forEach((_) => queue.removeFirst()), + throwsConcurrentModificationError); + }); + + test('removeLast', () { + expect(() => queue.forEach((_) => queue.removeLast()), + throwsConcurrentModificationError); + }); + + test('length=', () { + expect(() => queue.forEach((_) => queue.length = 1), + throwsConcurrentModificationError); + }); + }); + + test("QueueList()..addAll(['a', 'b']) patternQueue.cast()", () { + var patternQueue = QueueList()..addAll(['a', 'b']); + var stringQueue = patternQueue.cast(); + stringQueue.addAll(['c', 'd']); + stringQueue; + + expect(stringQueue, ['a', 'b', 'c', 'd']); + + expect(patternQueue, stringQueue); + }); + + test('QueueList().cast()', () { + QueueList stringQueue = QueueList(); + var numQueue = stringQueue.cast(); + numQueue; + }); + + test('QueueList().cast()', () { + var queue = QueueList(); + expect(queue.cast(), queue); + }); + } +} + +/// Returns a queue whose internal ring buffer is full enough that adding a new +/// element will expand it. +QueueList atCapacity() { + // Use addAll because `QueueList.from(list)` won't use the default initial + // capacity of 8. + return QueueList()..addAll([1, 2, 3, 4, 5, 6, 7]); +} + +/// Returns a queue whose internal tail has a lower index than its head. +QueueList withInternalGap() { + var queue = QueueList.from([null, null, null, null, 1, 2, 3, 4]); + for (var i = 0; i < 4; i++) { + queue.removeFirst(); + } + for (var i = 5; i < 8; i++) { + queue.addLast(i); + } + return queue; +} + +/// Returns a matcher that expects that a closure throws a +/// [ConcurrentModificationError]. +final throwsConcurrentModificationError = null; diff --git a/ohos/test_collection/lib/page/union_set_controller_test.dart b/ohos/test_collection/lib/page/union_set_controller_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9d2bc7a943b8c923bce9fdc64d5d12ccef68cba1 --- /dev/null +++ b/ohos/test_collection/lib/page/union_set_controller_test.dart @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class UnionSetControllerTestPage extends TestPage { + UnionSetControllerTestPage(String title, {Key? key}) + : super(title: title, key: key) { + late UnionSetController controller; + late Set innerSet; + + innerSet = {1, 2, 3}; + controller = UnionSetController()..add(innerSet); + + test('UnionSetController.set', () { + expect(controller.set, ([1, 2, 3])); + + controller.add({3, 4, 5}); + expect(controller.set, ([1, 2, 3, 4, 5])); + + controller.remove(innerSet); + expect(controller.set, ([3, 4, 5])); + + expect(controller.set, ([1, 2, 3])); + + controller.add({4, 5, 6}); + expect(controller.set, ([1, 2, 3, 4, 5, 6])); + + controller.remove(innerSet); + expect(controller.set, ([4, 5, 6])); + }); + } +} diff --git a/ohos/test_collection/lib/page/union_set_test.dart b/ohos/test_collection/lib/page/union_set_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..2cba446a193be3f724f3878dd99be9e6dfcbef72 --- /dev/null +++ b/ohos/test_collection/lib/page/union_set_test.dart @@ -0,0 +1,229 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class UnionSetTestPage extends TestPage { + UnionSetTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('with an empty outer set', () { + dynamic set; + + set = UnionSet({}); + + + test('UnionSet({}).length returns 0', () { + expect(set.length, (0)); + }); + + test('UnionSet({}).contains() returns false', () { + expect(set.contains(0), false); + expect(set.contains(null), false); + expect(set.contains('foo'), false); + }); + + test('UnionSet({}).lookup() returns null', () { + expect(set.lookup(0), null); + expect(set.lookup(null), null); + expect(set.lookup('foo'), null); + }); + + test('UnionSet({}).toSet() returns an empty set', () { + expect(set.toSet(), set.toSet().isEmpty); + expect(set.toSet(), set); + }); + + test("UnionSet({}).map() doesn't run on any elements", () { + expect(set.map((dynamic _) {}), null); + }); + }); + + group('', () { + dynamic set; + set = UnionSet.from([ + {1, 2}, + {3, 4}, + {5}, + {}, + ], disjoint: true); + + test('UnionSet().length returns the total length', () { + expect(set.length, (5)); + }); + + test('UnionSet().contains() returns whether any set contains the element', () { + expect(set.contains(1), true); + expect(set.contains(4), true); + expect(set.contains(5), true); + expect(set.contains(6), false); + }); + + test('UnionSet().lookup() returns elements that are in any set', () { + expect(set.lookup(1), (1)); + expect(set.lookup(4), (4)); + expect(set.lookup(5), (5)); + expect(set.lookup(6), null); + }); + + test('UnionSet().toSet() returns the union of all the sets', () { + expect(set.toSet(), ([1, 2, 3, 4, 5])); + expect(set.toSet(), set); + }); + + test('UnionSet().map() maps the elements', () { + expect(set.map((i) => i * 2), ([2, 4, 6, 8, 10])); + }); + }); + + group('', () { + dynamic set; + set = UnionSet.from([ + {1, 2, 3}, + {3, 4}, + {5, 1}, + {}, + ]); + + test('UnionSet.from().length returns the total length', () { + expect(set.length, (5)); + }); + + test('UnionSet.from().contains() returns whether any set contains the element', () { + expect(set.contains(1), true); + expect(set.contains(4), true); + expect(set.contains(5), true); + expect(set.contains(6), false); + }); + + test('UnionSet.from().lookup() returns elements that are in any set', () { + expect(set.lookup(1), (1)); + expect(set.lookup(4), (4)); + expect(set.lookup(5), (5)); + expect(set.lookup(6), null); + }); + + test('UnionSet.from().lookup() returns the first element in an ordered context', () { + var duration1 = Duration(seconds: 0); + var duration2 = Duration(seconds: 0); + expect(duration1, (duration2)); + expect(duration1, duration2); + + var set = UnionSet.from([ + {duration1}, + {duration2} + ]); + + expect(set.lookup(Duration(seconds: 0)), duration1); + }); + + test('UnionSet.from().toSet() returns the union of all the sets', () { + expect(set.toSet(), ([1, 2, 3, 4, 5])); + expect(set.toSet(), set); + }); + + test('UnionSet.from().map() maps the elements', () { + expect(set.map((i) => i * 2), ([2, 4, 6, 8, 10])); + }); + }); + + group('', () { + dynamic set; + // setUp(() { + var innerSet = {3, 7}; + set = UnionSet.from([ + {1, 2}, + {5}, + innerSet + ]); + + innerSet.add(4); + innerSet.remove(7); + // }); + + test('UnionSet.from().length returns the total length', () { + expect(set.length, (5)); + }); + + test('UnionSet.from().contains() returns true for a new element', () { + expect(set.contains(4), true); + }); + + test('UnionSet.from().contains() returns false for a removed element', () { + expect(set.contains(7), false); + }); + + test('UnionSet.from().lookup() returns a new element', () { + expect(set.lookup(4), (4)); + }); + + test("UnionSet.from().lookup() doesn't returns a removed element", () { + expect(set.lookup(7), null); + }); + + test('UnionSet.from().toSet() returns the union of all the sets', () { + expect(set.toSet(), ([1, 2, 3, 4, 5])); + expect(set.toSet(), set); + }); + + test('UnionSet.from().map() maps the elements', () { + expect(set.map((i) => i * 2), ([2, 4, 6, 8, 10])); + }); + }); + + group('', () { + dynamic set; + var innerSet = {6}; + var outerSet = { + {1, 2}, + {5}, + innerSet + }; + + set = UnionSet(outerSet); + outerSet.remove(innerSet); + outerSet.add({3, 4}); + + test('UnionSet().length returns the total length', () { + expect(set.length, (5)); + }); + + test('UnionSet().contains() returns true for a new element', () { + expect(set.contains(4), true); + }); + + test('UnionSet().contains() returns false for a removed element', () { + expect(set.contains(6), false); + }); + + test('UnionSet().lookup() returns a new element', () { + expect(set.lookup(4), (4)); + }); + + test("UnionSet().lookup() doesn't returns a removed element", () { + expect(set.lookup(6), null); + }); + + test('UnionSet().toSet() returns the union of all the sets', () { + expect(set.toSet(), ([1, 2, 3, 4, 5])); + expect(set.toSet(), set); + }); + + test('UnionSet().map() maps the elements', () { + expect(set.map((i) => i * 2), ([2, 4, 6, 8, 10])); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_collection/lib/page/unmodifiable_collection_test.dart b/ohos/test_collection/lib/page/unmodifiable_collection_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..63e76f0c0ddebe38e0555e8e9db2f6f682dcd136 --- /dev/null +++ b/ohos/test_collection/lib/page/unmodifiable_collection_test.dart @@ -0,0 +1,609 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:test_collection/common/test_page.dart'; + +class UnmodifiableCollectionTestPage extends TestPage { + UnmodifiableCollectionTestPage(String title, {Key? key}) + : super(title: title, key: key) { + var list = []; + testUnmodifiableList(list, UnmodifiableListView(list), 'empty'); + list = [42]; + testUnmodifiableList(list, UnmodifiableListView(list), 'single-42'); + list = [7]; + testUnmodifiableList(list, UnmodifiableListView(list), 'single!42'); + list = [1, 42, 10]; + testUnmodifiableList(list, UnmodifiableListView(list), 'three-42'); + list = [1, 7, 10]; + testUnmodifiableList(list, UnmodifiableListView(list), 'three!42'); + + list = []; + testNonGrowableList(list, NonGrowableListView(list), 'empty'); + list = [42]; + testNonGrowableList(list, NonGrowableListView(list), 'single-42'); + list = [7]; + testNonGrowableList(list, NonGrowableListView(list), 'single!42'); + list = [1, 42, 10]; + testNonGrowableList(list, NonGrowableListView(list), 'three-42'); + list = [1, 7, 10]; + testNonGrowableList(list, NonGrowableListView(list), 'three!42'); + + var aSet = {}; + testUnmodifiableSet(aSet, UnmodifiableSetView(aSet), 'empty'); + aSet = {}; + testUnmodifiableSet(aSet, const UnmodifiableSetView.empty(), 'const empty'); + aSet = {42}; + testUnmodifiableSet(aSet, UnmodifiableSetView(aSet), 'single-42'); + aSet = {7}; + testUnmodifiableSet(aSet, UnmodifiableSetView(aSet), 'single!42'); + aSet = {1, 42, 10}; + testUnmodifiableSet(aSet, UnmodifiableSetView(aSet), 'three-42'); + aSet = {1, 7, 10}; + testUnmodifiableSet(aSet, UnmodifiableSetView(aSet), 'three!42'); + } + + void testUnmodifiableList( + List original, List wrapped, String name) { + name = 'UnmodifiableListView-$name'; + testIterable(original, wrapped, name); + testReadList(original, wrapped, name); + testNoWriteList(original, wrapped, name); + testNoChangeLengthList(original, wrapped, name); + } + + void testNonGrowableList(List original, List wrapped, String name) { + name = 'NonGrowableListView-$name'; + testIterable(original, wrapped, name); + testReadList(original, wrapped, name); + testWriteList(original, wrapped, name); + testNoChangeLengthList(original, wrapped, name); + } + + void testUnmodifiableSet(Set original, Set wrapped, String name) { + name = 'UnmodifiableSetView-$name'; + testIterable(original, wrapped, name); + testReadSet(original, wrapped, name); + testNoChangeSet(original, wrapped, name); + } + + void testIterable( + Iterable original, Iterable wrapped, String name) { + test('$name - any', () { + expect(wrapped.any((x) => true), original.any((x) => true)); + expect(wrapped.any((x) => false), original.any((x) => false)); + }); + + test('$name - contains', () { + expect(wrapped.contains(0), original.contains(0)); + }); + + test('$name - elementAt', () { + if (original.isNotEmpty) { + expect(wrapped.elementAt(0), original.elementAt(0)); + } + }); + + test('$name - every', () { + expect(wrapped.every((x) => true), original.every((x) => true)); + expect(wrapped.every((x) => false), original.every((x) => false)); + }); + + test('$name - expand', () { + expect(wrapped.expand((x) => [x, x]), original.expand((x) => [x, x])); + }); + + test('$name - first', () { + if (original.isNotEmpty) { + expect(wrapped.first, original.first); + } + }); + + test('$name - firstWhere', () { + if (original.isNotEmpty) { + expect( + wrapped.firstWhere((_) => true), original.firstWhere((_) => true)); + } + }); + + test('$name - fold', () { + expect(wrapped.fold(0, (dynamic x, y) => x + y), + original.fold(0, (dynamic x, y) => x + y)); + }); + + test('$name - forEach', () { + var wrapCtr = 0; + var origCtr = 0; + wrapped.forEach((x) { + wrapCtr += x; + }); + original.forEach((x) { + origCtr += x; + }); + expect(wrapCtr, origCtr); + }); + + test('$name - isEmpty', () { + expect(wrapped.isEmpty, original.isEmpty); + }); + + test('$name - isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name - iterator', () { + Iterator wrapIter = wrapped.iterator; + Iterator origIter = original.iterator; + while (origIter.moveNext()) { + expect(wrapIter.moveNext(), (true)); + expect(wrapIter.current, (origIter.current)); + } + expect(wrapIter.moveNext(), (false)); + }); + + test('$name - join', () { + expect(wrapped.join(''), (original.join(''))); + expect(wrapped.join('-'), (original.join('-'))); + }); + + test('$name - last', () { + if (original.isNotEmpty) { + wrapped.last; + } + }); + + test('$name - lastWhere', () { + if (original.isNotEmpty) { + expect( + wrapped.lastWhere((_) => true), (original.lastWhere((_) => true))); + } + }); + + test('$name - length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name - map', () { + expect(wrapped.map((x) => '[$x]'), (original.map((x) => '[$x]'))); + }); + + test('$name - reduce', () { + if (original.isNotEmpty) { + expect(wrapped.reduce((x, y) => x + y), + (original.reduce((x, y) => x + y))); + } + }); + + test('$name - single', () { + if (original.length == 1) { + expect(wrapped.single, (original.single)); + } + }); + + test('$name - singleWhere', () { + if (original.length == 1) { + expect(wrapped.singleWhere((_) => true), + (original.singleWhere((_) => true))); + } + }); + + test('$name - skip', () { + expect(wrapped.skip(0), (original.skip(0))); + expect(wrapped.skip(1), (original.skip(1))); + expect(wrapped.skip(5), (original.skip(5))); + }); + + test('$name - skipWhile', () { + expect(wrapped.skipWhile((x) => true), (original.skipWhile((x) => true))); + expect( + wrapped.skipWhile((x) => false), (original.skipWhile((x) => false))); + expect(wrapped.skipWhile((x) => x != 42), + (original.skipWhile((x) => x != 42))); + }); + + test('$name - take', () { + expect(wrapped.take(0), (original.take(0))); + expect(wrapped.take(1), (original.take(1))); + expect(wrapped.take(5), (original.take(5))); + }); + + test('$name - takeWhile', () { + expect(wrapped.takeWhile((x) => true), (original.takeWhile((x) => true))); + expect( + wrapped.takeWhile((x) => false), (original.takeWhile((x) => false))); + expect(wrapped.takeWhile((x) => x != 42), + (original.takeWhile((x) => x != 42))); + }); + + test('$name - toList', () { + expect(wrapped.toList(), (original.toList())); + expect( + wrapped.toList(growable: false), (original.toList(growable: false))); + }); + + test('$name - toSet', () { + expect(wrapped.toSet(), (original.toSet())); + }); + + test('$name - where', () { + expect(wrapped.where((x) => true), (original.where((x) => true))); + expect(wrapped.where((x) => false), (original.where((x) => false))); + expect(wrapped.where((x) => x != 42), (original.where((x) => x != 42))); + }); + } + + void testReadList(List original, List wrapped, String name) { + test('$name - length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name - isEmpty', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name - isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name - []', () { + if (original.isNotEmpty) { + expect(wrapped[0], (original[0])); + } + }); + + test('$name - indexOf', () { + expect(wrapped.indexOf(42), (original.indexOf(42))); + }); + + test('$name - lastIndexOf', () { + expect(wrapped.lastIndexOf(42), (original.lastIndexOf(42))); + }); + + test('$name - getRange', () { + var len = original.length; + expect(wrapped.getRange(0, len), (original.getRange(0, len))); + expect( + wrapped.getRange(len ~/ 2, len), (original.getRange(len ~/ 2, len))); + expect(wrapped.getRange(0, len ~/ 2), (original.getRange(0, len ~/ 2))); + }); + + test('$name - sublist', () { + var len = original.length; + expect(wrapped.sublist(0), (original.sublist(0))); + expect(wrapped.sublist(len ~/ 2), (original.sublist(len ~/ 2))); + expect(wrapped.sublist(0, len ~/ 2), (original.sublist(0, len ~/ 2))); + }); + + test('$name - asMap', () { + expect(wrapped.asMap(), (original.asMap())); + }); + } + + void testNoWriteList(List original, List wrapped, String name) { + var copy = List.of(original); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name - []= throws', () { + wrapped[0] = 42; + }); + + testThrows('$name - sort throws', () { + wrapped.sort(); + }); + + testThrows('$name - fillRange throws', () { + wrapped.fillRange(0, wrapped.length, 42); + }); + + testThrows('$name - setRange throws', () { + wrapped.setRange( + 0, wrapped.length, Iterable.generate(wrapped.length, (i) => i)); + }); + + testThrows('$name - setAll throws', () { + wrapped.setAll(0, Iterable.generate(wrapped.length, (i) => i)); + }); + } + + void testWriteList(List original, List wrapped, String name) { + var copy = List.of(original); + + test('$name - []=', () { + if (original.isNotEmpty) { + var originalFirst = original[0]; + wrapped[0] = originalFirst + 1; + expect(original[0], (originalFirst + 1)); + original[0] = originalFirst; + } else { + wrapped[0] = 42; + } + }); + + test('$name - sort', () { + var sortCopy = List.of(original); + sortCopy.sort(); + wrapped.sort(); + expect(original, (sortCopy)); + original.setAll(0, copy); + }); + + test('$name - fillRange', () { + wrapped.fillRange(0, wrapped.length, 37); + for (var i = 0; i < original.length; i++) { + expect(original[i], (37)); + } + original.setAll(0, copy); + }); + + test('$name - setRange', () { + List reverseList = original.reversed.toList(); + wrapped.setRange(0, wrapped.length, reverseList); + expect(original, (reverseList)); + original.setAll(0, copy); + }); + + test('$name - setAll', () { + List reverseList = original.reversed.toList(); + wrapped.setAll(0, reverseList); + expect(original, (reverseList)); + original.setAll(0, copy); + }); + } + + void testNoChangeLengthList( + List original, List wrapped, String name) { + var copy = List.of(original); + + void testThrows(String name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name - length= throws', () { + wrapped.length = 100; + }); + + testThrows('$name - add throws', () { + wrapped.add(42); + }); + + testThrows('$name - addAll throws', () { + wrapped.addAll([42]); + }); + + testThrows('$name - insert throws', () { + wrapped.insert(0, 42); + }); + + testThrows('$name - insertAll throws', () { + wrapped.insertAll(0, [42]); + }); + + testThrows('$name - remove throws', () { + wrapped.remove(42); + }); + + testThrows('$name - removeAt throws', () { + wrapped.removeAt(0); + }); + + testThrows('$name - removeLast throws', () { + wrapped.removeLast(); + }); + + testThrows('$name - removeWhere throws', () { + wrapped.removeWhere((element) => false); + }); + + testThrows('$name - retainWhere throws', () { + wrapped.retainWhere((element) => true); + }); + + testThrows('$name - removeRange throws', () { + wrapped.removeRange(0, wrapped.length); + }); + + testThrows('$name - replaceRange throws', () { + wrapped.replaceRange(0, wrapped.length, [42]); + }); + + testThrows('$name - clear throws', () { + wrapped.clear(); + }); + } + + void testReadSet(Set original, Set wrapped, String name) { + var copy = Set.of(original); + + test('$name - containsAll', () { + expect(wrapped.containsAll(copy), true); + expect(wrapped.containsAll(copy.toList()), true); + expect(wrapped.containsAll([]), true); + expect(wrapped.containsAll([42]), (original.containsAll([42]))); + }); + + test('$name - intersection', () { + expect(wrapped.intersection({}), wrapped.intersection({}).isEmpty); + expect(wrapped.intersection(copy), (original)); + expect(wrapped.intersection({42}), + Set.of(original.contains(42) ? [42] : [])); + }); + + test('$name - union', () { + expect(wrapped.union({}), (original)); + expect(wrapped.union(copy), (original)); + expect(wrapped.union({42}), (original.union({42}))); + }); + + test('$name - difference', () { + expect(wrapped.difference({}), (original)); + expect(wrapped.difference(copy), wrapped.difference(copy).isEmpty); + expect(wrapped.difference({42}), (original.difference({42}))); + }); + } + + void testNoChangeSet(Set original, Set wrapped, String name) { + var originalElements = original.toList(); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original.toList(), (originalElements)); + }); + } + + testThrows('$name - add throws', () { + wrapped.add(42); + }); + + testThrows('$name - addAll throws', () { + wrapped.addAll([42]); + }); + + testThrows('$name - addAll empty throws', () { + wrapped.addAll([]); + }); + + testThrows('$name - remove throws', () { + wrapped.remove(42); + }); + + testThrows('$name - removeAll throws', () { + wrapped.removeAll([42]); + }); + + testThrows('$name - removeAll empty throws', () { + wrapped.removeAll([]); + }); + + testThrows('$name - retainAll throws', () { + wrapped.retainAll([42]); + }); + + testThrows('$name - removeWhere throws', () { + wrapped.removeWhere((_) => false); + }); + + testThrows('$name - retainWhere throws', () { + wrapped.retainWhere((_) => true); + }); + + testThrows('$name - clear throws', () { + wrapped.clear(); + }); + } + + void testReadMap(Map original, Map wrapped, String name) { + test('$name length', () { + expect(wrapped.length, (original.length)); + }); + + test('$name isEmpty', () { + expect(wrapped.isEmpty, (original.isEmpty)); + }); + + test('$name isNotEmpty', () { + expect(wrapped.isNotEmpty, (original.isNotEmpty)); + }); + + test('$name operator[]', () { + expect(wrapped[0], (0)); + expect(wrapped[999], (999)); + }); + + test('$name containsKey', () { + expect(wrapped.containsKey(0), (original.containsKey(0))); + expect(wrapped.containsKey(999), (original.containsKey(999))); + }); + + test('$name containsValue', () { + expect(wrapped.containsValue(0), (original.containsValue(0))); + expect(wrapped.containsValue(999), (original.containsValue(999))); + }); + + test('$name forEach', () { + var origCnt = 0; + var wrapCnt = 0; + wrapped.forEach((k, v) { + wrapCnt += 1 << k + 3 * v; + }); + original.forEach((k, v) { + origCnt += 1 << k + 3 * v; + }); + expect(wrapCnt, (origCnt)); + }); + + test('$name keys', () { + expect(wrapped.keys, (original.keys)); + }); + + test('$name values', () { + expect(wrapped.values, (original.values)); + }); + } + + void testNoChangeMap( + Map original, Map wrapped, String name) { + var copy = Map.of(original); + + void testThrows(name, thunk) { + test(name, () { + thunk; + // No modifications happened. + expect(original, (copy)); + }); + } + + testThrows('$name operator[]= throws', () { + wrapped[0] = 42; + }); + + testThrows('$name putIfAbsent throws', () { + wrapped.putIfAbsent(0, () => 42); + }); + + testThrows('$name addAll throws', () { + wrapped.addAll({42: 42}); + }); + + testThrows('$name addAll empty throws', () { + wrapped.addAll({}); + }); + + testThrows('$name remove throws', () { + wrapped.remove(0); + }); + + testThrows('$name clear throws', () { + wrapped.clear(); + }); + } +} diff --git a/ohos/test_collection/lib/page/wrapper_test.dart b/ohos/test_collection/lib/page/wrapper_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..6aae3b1bd8d35ed386db84b41c001220f796deff --- /dev/null +++ b/ohos/test_collection/lib/page/wrapper_test.dart @@ -0,0 +1,705 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:collection'; + +import 'package:collection/collection.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; +import 'mirrors.dart'; + +// Test that any member access/call on the wrapper object is equal to +// an expected access on the wrapped object. +// This is implemented by capturing accesses using noSuchMethod and comparing +// them to expected accesses captured previously. + +// Compare two Invocations for having equal type and arguments. +void testInvocations(Invocation i1, Invocation i2) { + var name = '${i1.memberName}'; + expect(i1.isGetter, (i2.isGetter)); + expect(i1.isSetter, (i2.isSetter)); + expect(i1.memberName, (i2.memberName)); + expect(i1.positionalArguments, (i2.positionalArguments)); + expect(i1.namedArguments, (i2.namedArguments)); +} + +/// Utility class to record a member access and a member access on a wrapped +/// object, and compare them for equality. +/// +/// Use as `(expector..someAccess()).equals.someAccess();`. +/// Alle the intercepted member accesses returns `null`. +abstract class Expector { + dynamic wrappedChecker(Invocation i); + + // After calling any member on the Expector, equals is an object that expects + // the *same* invocation on the wrapped object. + dynamic equals; + + InstanceMirror get mirror; + + @override + dynamic noSuchMethod(Invocation actual) { + equals = wrappedChecker(actual); + return mirror.delegate(actual); + } + + @override + String toString() { + // Cannot return an _Equals object since toString must return a String. + // Just set equals and return a string. + equals = wrappedChecker(toStringInvocation); + return ''; + } +} + +// Parameterization of noSuchMethod. Calls [_action] on every +// member invocation. +class InvocationChecker { + final Invocation _expected; + final InstanceMirror _instanceMirror; + + InvocationChecker(this._expected, this._instanceMirror); + + @override + dynamic noSuchMethod(Invocation actual) { + testInvocations(_expected, actual); + return _instanceMirror.delegate(actual); + } + + @override + String toString() { + testInvocations(_expected, toStringInvocation); + return ''; + } +// Could also handle runtimeType, hashCode and == the same way as +// toString, but we are not testing them since collections generally +// don't override those and so the wrappers don't forward those. +} + +final toStringInvocation = Invocation.method(#toString, const []); + +// InvocationCheckers with types Queue, Set, List or Iterable to allow them as +// argument to DelegatingIterable/Set/List/Queue. +class IterableInvocationChecker extends InvocationChecker + implements Iterable { + IterableInvocationChecker(Invocation expected, InstanceMirror mirror) + : super(expected, mirror); +} + +class ListInvocationChecker extends InvocationChecker implements List { + ListInvocationChecker(Invocation expected, InstanceMirror mirror) + : super(expected, mirror); +} + +class SetInvocationChecker extends InvocationChecker implements Set { + SetInvocationChecker(Invocation expected, InstanceMirror mirror) + : super(expected, mirror); +} + +class QueueInvocationChecker extends InvocationChecker implements Queue { + QueueInvocationChecker(Invocation expected, InstanceMirror mirror) + : super(expected, mirror); +} + +class MapInvocationChecker extends InvocationChecker + implements Map { + MapInvocationChecker(Invocation expected, InstanceMirror mirror) + : super(expected, mirror); +} + +// Expector that wraps in DelegatingIterable. +class IterableExpector extends Expector implements Iterable { + @override + final InstanceMirror mirror; + + IterableExpector(Iterable realInstance) : mirror = reflect(realInstance); + + @override + dynamic wrappedChecker(Invocation i) => + DelegatingIterable(IterableInvocationChecker(i, mirror)); +} + +// Expector that wraps in DelegatingList. +class ListExpector extends IterableExpector implements List { + ListExpector(List realInstance) : super(realInstance); + + @override + dynamic wrappedChecker(Invocation i) => + DelegatingList(ListInvocationChecker(i, mirror)); +} + +// Expector that wraps in DelegatingSet. +class SetExpector extends IterableExpector implements Set { + SetExpector(Set realInstance) : super(realInstance); + + @override + dynamic wrappedChecker(Invocation i) => + DelegatingSet(SetInvocationChecker(i, mirror)); +} + +// Expector that wraps in DelegatingSet. +class QueueExpector extends IterableExpector implements Queue { + QueueExpector(Queue realInstance) : super(realInstance); + + @override + dynamic wrappedChecker(Invocation i) => + DelegatingQueue(QueueInvocationChecker(i, mirror)); +} + +// Expector that wraps in DelegatingMap. +class MapExpector extends Expector implements Map { + @override + final InstanceMirror mirror; + + MapExpector(Map realInstance) : mirror = reflect(realInstance); + + @override + dynamic wrappedChecker(Invocation i) => + DelegatingMap(MapInvocationChecker(i, mirror)); +} + +// Utility values to use as arguments in calls. +// ignore: prefer_void_to_null +Null func0() => null; + +dynamic func1(dynamic x) => null; + +dynamic func2(dynamic x, dynamic y) => null; + +bool boolFunc(dynamic x) => true; + +Iterable expandFunc(dynamic x) => [x]; + +dynamic foldFunc(dynamic previous, dynamic next) => previous; + +int compareFunc(dynamic x, dynamic y) => 0; +var val = 10; + +class WrapperTestPage extends TestPage { + WrapperTestPage(String title, {Key? key}) : super(title: title, key: key) { + void testIterable(IterableExpector expect) { + (expect..any(boolFunc)).equals.any(boolFunc); + (expect..contains(val)).equals.contains(val); + (expect..elementAt(0)).equals.elementAt(0); + (expect..every(boolFunc)).equals.every(boolFunc); + (expect..expand(expandFunc)).equals.expand(expandFunc); + (expect..first).equals.first; + // Default values of the Iterable interface will be added in the + // second call to firstWhere, so we must record them in our + // expectation (which doesn't have the interface implemented or + // its default values). + (expect..firstWhere(boolFunc, orElse: null)).equals.firstWhere(boolFunc); + (expect..firstWhere(boolFunc, orElse: func0)) + .equals + .firstWhere(boolFunc, orElse: func0); + (expect..fold(42, foldFunc)).equals.fold(42, foldFunc); + (expect..forEach(boolFunc)).equals.forEach(boolFunc); + (expect..isEmpty).equals.isEmpty; + (expect..isNotEmpty).equals.isNotEmpty; + (expect..iterator).equals.iterator; + (expect..join('')).equals.join(); + (expect..join('X')).equals.join('X'); + (expect..last).equals.last; + (expect..lastWhere(boolFunc, orElse: null)).equals.lastWhere(boolFunc); + (expect..lastWhere(boolFunc, orElse: func0)) + .equals + .lastWhere(boolFunc, orElse: func0); + (expect..length).equals.length; + (expect..map(func1)).equals.map(func1); + (expect..reduce(func2)).equals.reduce(func2); + (expect..single).equals.single; + (expect..singleWhere(boolFunc, orElse: null)) + .equals + .singleWhere(boolFunc); + (expect..skip(5)).equals.skip(5); + (expect..skipWhile(boolFunc)).equals.skipWhile(boolFunc); + (expect..take(5)).equals.take(5); + (expect..takeWhile(boolFunc)).equals.takeWhile(boolFunc); + (expect..toList(growable: true)).equals.toList(); + (expect..toList(growable: true)).equals.toList(growable: true); + (expect..toList(growable: false)).equals.toList(growable: false); + (expect..toSet()).equals.toSet(); + (expect..toString()).equals.toString(); + (expect..where(boolFunc)).equals.where(boolFunc); + } + + void testList(ListExpector expect) { + testIterable(expect); + // Later expects require at least 5 items + (expect..add(val)).equals.add(val); + (expect..addAll([val, val, val, val])) + .equals + .addAll([val, val, val, val]); + + (expect..[4]).equals[4]; + (expect..[4] = 5).equals[4] = 5; + + (expect..asMap()).equals.asMap(); + (expect..fillRange(4, 5, null)).equals.fillRange(4, 5); + (expect..fillRange(4, 5, val)).equals.fillRange(4, 5, val); + (expect..getRange(4, 5)).equals.getRange(4, 5); + (expect..indexOf(val, 0)).equals.indexOf(val); + (expect..indexOf(val, 4)).equals.indexOf(val, 4); + (expect..insert(4, val)).equals.insert(4, val); + (expect..insertAll(4, [val])).equals.insertAll(4, [val]); + (expect..lastIndexOf(val, null)).equals.lastIndexOf(val); + (expect..lastIndexOf(val, 4)).equals.lastIndexOf(val, 4); + (expect..replaceRange(4, 5, [val])).equals.replaceRange(4, 5, [val]); + (expect..retainWhere(boolFunc)).equals.retainWhere(boolFunc); + (expect..reversed).equals.reversed; + (expect..setAll(4, [val])).equals.setAll(4, [val]); + (expect..setRange(4, 5, [val], 0)).equals.setRange(4, 5, [val]); + (expect..setRange(4, 5, [val, val], 1)) + .equals + .setRange(4, 5, [val, val], 1); + (expect..sort()).equals.sort(); + (expect..sort(compareFunc)).equals.sort(compareFunc); + (expect..sublist(4, null)).equals.sublist(4); + (expect..sublist(4, 5)).equals.sublist(4, 5); + + // Do destructive apis last so other ones can work properly + (expect..removeAt(4)).equals.removeAt(4); + (expect..remove(val)).equals.remove(val); + (expect..removeLast()).equals.removeLast(); + (expect..removeRange(4, 5)).equals.removeRange(4, 5); + (expect..removeWhere(boolFunc)).equals.removeWhere(boolFunc); + (expect..length = 5).equals.length = 5; + (expect..clear()).equals.clear(); + } + + void testSet(SetExpector expect) { + testIterable(expect); + var set = {}; + (expect..add(val)).equals.add(val); + (expect..addAll([val])).equals.addAll([val]); + (expect..clear()).equals.clear(); + (expect..containsAll([val])).equals.containsAll([val]); + (expect..difference(set)).equals.difference(set); + (expect..intersection(set)).equals.intersection(set); + (expect..remove(val)).equals.remove(val); + (expect..removeAll([val])).equals.removeAll([val]); + (expect..removeWhere(boolFunc)).equals.removeWhere(boolFunc); + (expect..retainAll([val])).equals.retainAll([val]); + (expect..retainWhere(boolFunc)).equals.retainWhere(boolFunc); + (expect..union(set)).equals.union(set); + } + + void testQueue(QueueExpector expect) { + testIterable(expect); + (expect..add(val)).equals.add(val); + (expect..addAll([val])).equals.addAll([val]); + (expect..addFirst(val)).equals.addFirst(val); + (expect..addLast(val)).equals.addLast(val); + (expect..remove(val)).equals.remove(val); + (expect..removeFirst()).equals.removeFirst(); + (expect..removeLast()).equals.removeLast(); + (expect..clear()).equals.clear(); + } + + void testMap(MapExpector expect) { + var map = {}; + (expect..[val]).equals[val]; + (expect..[val] = val).equals[val] = val; + (expect..addAll(map)).equals.addAll(map); + (expect..clear()).equals.clear(); + (expect..containsKey(val)).equals.containsKey(val); + (expect..containsValue(val)).equals.containsValue(val); + (expect..forEach(func2)).equals.forEach(func2); + (expect..isEmpty).equals.isEmpty; + (expect..isNotEmpty).equals.isNotEmpty; + (expect..keys).equals.keys; + (expect..length).equals.length; + (expect..putIfAbsent(val, func0)).equals.putIfAbsent(val, func0); + (expect..remove(val)).equals.remove(val); + (expect..values).equals.values; + (expect..toString()).equals.toString(); + } + + // Runs tests of Set behavior. + // + // [setUpSet] should return a set with two elements: "foo" and "bar". + void testTwoElementSet(Set Function() setUpSet) { + group('with two elements', () { + Set set = setUpSet(); + + test('.any', () { + expect(set.any((element) => element == 'foo'), true); + expect(set.any((element) => element == 'baz'), false); + }); + + test('.elementAt', () { + Set set = setUpSet(); + set.any((element) => element == 'foo'); + set.any((element) => element == 'baz'); + expect(set.elementAt(0), ('foo')); + expect(set.elementAt(1), ('bar')); + }); + + test('.every', () { + expect(set.every((element) => element == 'foo'), false); + expect(set.every((element) => true), true); + }); + + test('.expand', () { + expect(set.expand((element) { + return [element.substring(0, 1), element.substring(1)]; + }), (['f', 'oo', 'b', 'ar'])); + }); + + test('.first', () { + expect(set.first, ('foo')); + }); + + test('.firstWhere', () { + expect(set.firstWhere((element) => true), ('foo')); + expect(set.firstWhere((element) => element.startsWith('b')), ('bar')); + }); + + test('.fold', () { + expect( + set.fold( + 'start', (dynamic previous, element) => previous + element), + ('startfoobar')); + }); + + test('.forEach', () { + var values = []; + set.forEach(values.add); + expect(values, (['foo', 'bar'])); + }); + + test('.iterator', () { + var values = []; + for (var element in set) { + values.add(element); + } + expect(values, (['foo', 'bar'])); + }); + + test('.join', () { + expect(set.join(', '), ('foo, bar')); + }); + + test('.last', () { + expect(set.last, ('bar')); + }); + + test('.lastWhere', () { + expect(set.lastWhere((element) => true), ('bar')); + expect(set.lastWhere((element) => element.startsWith('f')), ('foo')); + }); + + test('.map', () { + expect(set.map((element) => element.substring(1)), (['oo', 'ar'])); + }); + + test('.reduce', () { + expect(set.reduce((previous, element) => previous + element), + ('foobar')); + }); + + test('.singleWhere', () { + Set set = setUpSet(); + expect(() => set.singleWhere((element) => element == 'baz'), + () => set.singleWhere((element) => element == 'baz')); + expect(() => set.singleWhere((element) => element == 'foo'), 'foo'); + expect(() => set.singleWhere((element) => true), + () => set.singleWhere((element) => true)); + }); + + test('.skip', () { + expect(set.skip(0), (['foo', 'bar'])); + expect(set.skip(1), (['bar'])); + expect(set.skip(2), ([])); + }); + + test('.skipWhile', () { + expect( + set.skipWhile((element) => element.startsWith('f')), (['bar'])); + expect(set.skipWhile((element) => element.startsWith('z')), + (['foo', 'bar'])); + expect(set.skipWhile((element) => true), ([])); + }); + + test('.take', () { + expect(set.take(0), ([])); + expect(set.take(1), (['foo'])); + expect(set.take(2), (['foo', 'bar'])); + }); + + test('.takeWhile', () { + expect( + set.takeWhile((element) => element.startsWith('f')), (['foo'])); + expect(set.takeWhile((element) => element.startsWith('z')), ([])); + expect(set.takeWhile((element) => true), (['foo', 'bar'])); + }); + + test('.toList', () { + expect(set.toList(), (['foo', 'bar'])); + set.toList(growable: false); + expect(() => set.toList(growable: false).add('baz'), + () => set.toList(growable: false).add('baz')); + expect(set.toList()..add('baz'), (['foo', 'bar', 'baz'])); + }); + + test('.toSet', () { + expect(set.toSet(), ({'foo', 'bar'})); + }); + + test('.where', () { + expect(set.where((element) => element.startsWith('f')), (['foo'])); + expect(set.where((element) => element.startsWith('z')), ([])); + expect(set.whereType(), (['foo', 'bar'])); + }); + + test('.containsAll', () { + expect(set.containsAll(['foo', 'bar']), true); + expect(set.containsAll(['foo']), true); + expect(set.containsAll(['foo', 'bar', 'qux']), false); + }); + + test('.difference', () { + expect(set.difference({'foo', 'baz'}), ({'bar'})); + }); + + test('.intersection', () { + expect(set.intersection({'foo', 'baz'}), ({'foo'})); + }); + + test('.union', () { + expect(set.union({'foo', 'baz'}), ({'foo', 'bar', 'baz'})); + }); + }); + } + + /// 这里因为原来的dart:mirrors缺失,会有异常情况 + // test('Iterable', () { + // testIterable(IterableExpector([1])); + // }); + // + // test('List', () { + // testList(ListExpector([1])); + // }); + // + // test('Set', () { + // testSet(SetExpector({1})); + // }); + // + // test('Queue', () { + // testQueue(QueueExpector(Queue.of([1]))); + // }); + // + // test('Map', () { + // testMap(MapExpector({'a': 'b'})); + // }); + + group('MapKeySet', () { + Map map = {}; + Set set = MapKeySet(map); + + testTwoElementSet(() { + map['foo'] = 1; + map['bar'] = 2; + return set; + }); + + test('.single', () { + Map map = {}; + map['foo'] = 1; + Set set = MapKeySet(map); + expect(set.single, ('foo')); + }); + + test('.toString', () { + expect(set.toString(), ('{}')); + map['foo'] = 1; + map['bar'] = 2; + expect(set.toString(), ('{foo, bar}')); + }); + + test('.contains', () { + expect(set.contains('foo'), false); + map['foo'] = 1; + expect(set.contains('foo'), true); + }); + + test('.isEmpty', () { + expect(set.isEmpty, true); + map['foo'] = 1; + expect(set.isEmpty, false); + }); + + test('.isNotEmpty', () { + expect(set.isNotEmpty, false); + map['foo'] = 1; + expect(set.isNotEmpty, true); + }); + + test('.length', () { + expect(set.length, (0)); + map['foo'] = 1; + expect(set.length, (1)); + map['bar'] = 2; + expect(set.length, (2)); + }); + + test('is unmodifiable, 此处会报错', () { + set.add('baz'); + set.addAll(['baz', 'bang']); + set.remove('foo'); + set.removeAll(['baz', 'bang']); + set.retainAll(['foo']); + set.removeWhere((_) => true); + set.retainWhere((_) => true); + set.clear(); + expect(true, true); + }); + }); + + group('MapValueSet', () { + Map map = {}; + Set set = + MapValueSet(map, (string) => string.substring(0, 1)); + + testTwoElementSet(() { + map['f'] = 'foo'; + map['b'] = 'bar'; + return set; + }); + + test('.single', () { + Map map = {}; + Set set = MapValueSet( + map, (string) => string.substring(0, 1)); + set.clear(); + set.add('1'); + expect(set.single, set.single); + }); + + test('.toString', () { + expect(set.toString(), ('{}')); + map['f'] = 'foo'; + map['b'] = 'bar'; + expect(set.toString(), ('{foo, bar}')); + }); + + test('.contains', () { + expect(set.contains('foo'), false); + map['f'] = 'foo'; + expect(set.contains('foo'), true); + expect(set.contains('fblthp'), true); + }); + + test('.isEmpty', () { + expect(set.isEmpty, true); + map['f'] = 'foo'; + expect(set.isEmpty, false); + }); + + test('.isNotEmpty', () { + expect(set.isNotEmpty, false); + map['f'] = 'foo'; + expect(set.isNotEmpty, true); + }); + + test('.length', () { + expect(set.length, (0)); + map['f'] = 'foo'; + expect(set.length, (1)); + map['b'] = 'bar'; + expect(set.length, (2)); + }); + + test('.lookup', () { + map['f'] = 'foo'; + expect(set.lookup('fblthp'), ('foo')); + expect(set.lookup('bar'), null); + }); + + test('.add', () { + set.add('foo'); + set.add('bar'); + expect(map, ({'f': 'foo', 'b': 'bar'})); + }); + + test('.addAll', () { + set.addAll(['foo', 'bar']); + expect(map, ({'f': 'foo', 'b': 'bar'})); + }); + + test('.clear', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + set.clear(); + expect(map.isEmpty, true); + }); + + test('.remove', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + set.remove('fblthp'); + expect(map, ({'b': 'bar'})); + }); + + test('.removeAll', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + map['q'] = 'qux'; + set.removeAll(['fblthp', 'qux']); + expect(map, ({'b': 'bar'})); + }); + + test('.removeWhere', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + map['q'] = 'qoo'; + set.removeWhere((element) => element.endsWith('o')); + expect(map, ({'b': 'bar'})); + }); + + test('.retainAll', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + map['q'] = 'qux'; + set.retainAll(['fblthp', 'qux']); + expect(map, ({'f': 'foo', 'q': 'qux'})); + }); + + test('.retainAll respects an unusual notion of equality', () { + map = HashMap( + equals: (value1, value2) => + value1.toLowerCase() == value2.toLowerCase(), + hashCode: (value) => value.toLowerCase().hashCode); + set = MapValueSet( + map, (string) => string.substring(0, 1)); + + map['f'] = 'foo'; + map['B'] = 'bar'; + map['Q'] = 'qux'; + set.retainAll(['fblthp', 'qux']); + expect(map, ({'f': 'foo', 'Q': 'qux'})); + }); + + test('.retainWhere', () { + map['f'] = 'foo'; + map['b'] = 'bar'; + map['q'] = 'qoo'; + set.retainWhere((element) => element.endsWith('o')); + expect(map, ({'f': 'foo', 'q': 'qoo'})); + }); + }); + } +} diff --git a/ohos/test_collection/ohos/.gitignore b/ohos/test_collection/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_collection/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_collection/ohos/AppScope/app.json5 b/ohos/test_collection/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5be322ddf25a946762a747cec7953223ffe4386f --- /dev/null +++ b/ohos/test_collection/ohos/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "com.example.test_collection", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_collection/ohos/AppScope/resources/base/element/string.json b/ohos/test_collection/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3b13f372c50641375a42904890e0df5157384c8a --- /dev/null +++ b/ohos/test_collection/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_collection" + } + ] +} diff --git a/ohos/test_collection/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_collection/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_collection/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_collection/ohos/build-profile.json5 b/ohos/test_collection/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..93626c5b0d752f5879852e0dd09eb93ad0a63002 --- /dev/null +++ b/ohos/test_collection/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_collection.cer", + "storePassword": "0000001B70E6BF4044E317C7B73B9F40078FCA8C8288CACF66F3137D10BA4D0592EF03B3C7B24DBD6878F0", + "keyAlias": "debugKey", + "keyPassword": "0000001B7A1997654E4D0F0912608E0B312AD79847F56F7A1279614800ACF6FAB66C64DCE1161160344459", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_collection.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_collection.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_collection/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_collection/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_collection/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_collection/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_collection/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_collection/ohos/dependencies/rollup.tgz b/ohos/test_collection/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_collection/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_collection/ohos/dta/icudtl.dat b/ohos/test_collection/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_collection/ohos/dta/icudtl.dat differ diff --git a/ohos/test_collection/ohos/entry/.gitignore b/ohos/test_collection/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_collection/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/build-profile.json5 b/ohos/test_collection/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_collection/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/hvigorfile.ts b/ohos/test_collection/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_collection/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_collection/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_collection/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_collection/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_collection/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_collection/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_collection/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_collection/ohos/entry/oh-package.json5 b/ohos/test_collection/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d11c9cb13ab285e6a35ce0294007dce26e623067 --- /dev/null +++ b/ohos/test_collection/ohos/entry/oh-package.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_collection/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_collection/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_collection/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_collection/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/main/module.json5 b/ohos/test_collection/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_collection/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_collection/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_collection/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_collection/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_collection/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_collection/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_collection/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_collection/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_collection/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/module.json5 b/ohos/test_collection/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_collection/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_collection/ohos/har/flutter_embedding.har b/ohos/test_collection/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_collection/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_collection/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_collection/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_collection/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_collection/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_collection/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_collection/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_collection/ohos/har/flutter_embedding.har.release.10 b/ohos/test_collection/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_collection/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_collection/ohos/har/flutter_embedding.har.release.9 b/ohos/test_collection/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_collection/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_collection/ohos/har/libflutter.so.debug.10 b/ohos/test_collection/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_collection/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_collection/ohos/har/libflutter.so.release.10 b/ohos/test_collection/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_collection/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_collection/ohos/hvigor/hvigor-config.json5 b/ohos/test_collection/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_collection/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_collection/ohos/hvigor/hvigor-wrapper.js b/ohos/test_collection/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..ce46aa6fa02c8e8e049a7e85ee0b3d708046567d --- /dev/null +++ b/ohos/test_collection/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_collection/ohos/hvigorfile.ts b/ohos/test_collection/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_collection/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_collection/ohos/hvigorw b/ohos/test_collection/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_collection/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_collection/ohos/hvigorw.bat b/ohos/test_collection/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..9c0bce666c29dcc3ef35dae78c7be9cafa1267ae --- /dev/null +++ b/ohos/test_collection/ohos/hvigorw.bat @@ -0,0 +1,79 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_collection/ohos/oh-package-lock.json5 b/ohos/test_collection/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..321d36e7faa83a017ff14b0c6f33427a65d510af --- /dev/null +++ b/ohos/test_collection/ohos/oh-package-lock.json5 @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_collection/ohos/oh-package.json5 b/ohos/test_collection/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..315df7203af813f7da1cbb5a3819d121081032fa --- /dev/null +++ b/ohos/test_collection/ohos/oh-package.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_collection/pubspec.yaml b/ohos/test_collection/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..589971bbbfabf48c7bd6171863a7b6db086d3655 --- /dev/null +++ b/ohos/test_collection/pubspec.yaml @@ -0,0 +1,31 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_collection +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + collection: 1.17.0 +dev_dependencies: + lints: ^1.0.0 + test: ^1.16.0 +flutter: + uses-material-design: true \ No newline at end of file diff --git a/ohos/test_convert/.gitignore b/ohos/test_convert/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_convert/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_convert/.metadata b/ohos/test_convert/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..c64177774df6a3ceb0f67e70374ac42f58b6bccb --- /dev/null +++ b/ohos/test_convert/.metadata @@ -0,0 +1,45 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_convert/README.md b/ohos/test_convert/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_convert/analysis_options.yaml b/ohos/test_convert/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_convert/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_convert/lib/common/base_page.dart b/ohos/test_convert/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_convert/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_convert/lib/common/item_widget.dart b/ohos/test_convert/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_convert/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_convert/lib/common/main_item_widget.dart b/ohos/test_convert/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_convert/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_convert/lib/common/test_model_app.dart b/ohos/test_convert/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_convert/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_convert/lib/common/test_page.dart b/ohos/test_convert/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_convert/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_convert/lib/common/test_route.dart b/ohos/test_convert/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_convert/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_convert/lib/main.dart b/ohos/test_convert/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..91cde873959c50b272fee413b928091f7b52fac4 --- /dev/null +++ b/ohos/test_convert/lib/main.dart @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_convert/src/accumulator_sink_test.dart'; +import 'package:test_convert/src/byte_accumulator_sink_test.dart'; +import 'package:test_convert/src/codepage_test.dart'; +import 'package:test_convert/src/fixed_datetime_formatter_test.dart'; +import 'package:test_convert/src/hex_test.dart'; +import 'package:test_convert/src/identity_codec_test.dart'; +import 'package:test_convert/src/percent_test.dart'; +import 'package:test_convert/src/string_accumulator_sink_test.dart'; +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + final app = [ + MainItem('AccumulatorSinkTestPage', AccumulatorSinkTestPage('AccumulatorSinkTestPage')), + MainItem('ByteAccumulatorSinkTestPage', ByteAccumulatorSinkTestPage('ByteAccumulatorSinkTestPage')), + MainItem('CodepageTestPage', CodepageTestPage('CodepageTestPage')), + MainItem('FixedDatetimeFormatterTestPage', FixedDatetimeFormatterTestPage('FixedDatetimeFormatterTestPage')), + MainItem('HexTestPage', HexTestPage('HexTestPage')), + MainItem('IdentityCodecTestPage', IdentityCodecTestPage('IdentityCodecTestPage')), + MainItem('PercentTestPage', PercentTestPage('PercentTestPage')), + MainItem('StringAccumulatorSinkTestPage', StringAccumulatorSinkTestPage('StringAccumulatorSinkTestPage')), + ]; + + runApp(TestModelApp(appName: 'convert', data: app)); +} diff --git a/ohos/test_convert/lib/src/accumulator_sink_test.dart b/ohos/test_convert/lib/src/accumulator_sink_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4a2b57b1cf83844fb85eb0b76e31a68e122d0cb2 --- /dev/null +++ b/ohos/test_convert/lib/src/accumulator_sink_test.dart @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class AccumulatorSinkTestPage extends TestPage { + AccumulatorSinkTestPage(String title, {Key? key}) + : super(title: title, key: key) { + test("在添加事件时提供对事件的访问", () { + sink = AccumulatorSink(); + expect(sink.events.isEmpty, sink.events.isEmpty); + + sink.add(1); + expect(sink.events, ([1])); + + sink.add(2); + expect(sink.events, ([1, 2])); + + sink.add(3); + expect(sink.events, ([1, 2, 3])); + }); + + test('clear()清除事件', () { + sink + ..add(1) + ..add(2) + ..add(3); + expect(sink.events, ([1, 2, 3])); + + sink.clear(); + expect(sink.events.isEmpty, sink.events.isEmpty); + + sink + ..add(4) + ..add(5) + ..add(6); + expect(sink.events, ([4, 5, 6])); + }); + + test('指示AccumulatorSink是否关闭', () { + sink = AccumulatorSink(); + expect(sink.isClosed, false); + sink.close(); + expect(sink.isClosed, true); + }); + + test("不允许在close()之后调用add(),此处应为x", () { + sink.close(); + sink.add(1); + expect(() => sink.add(1), () => sink.add(1)); + }); + } + + AccumulatorSink sink = AccumulatorSink(); +} diff --git a/ohos/test_convert/lib/src/byte_accumulator_sink_test.dart b/ohos/test_convert/lib/src/byte_accumulator_sink_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..7c9da7b7f2da1e2f851bd47e5ebe5ab6e5cd9b75 --- /dev/null +++ b/ohos/test_convert/lib/src/byte_accumulator_sink_test.dart @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class ByteAccumulatorSinkTestPage extends TestPage { + ByteAccumulatorSinkTestPage(String title, {Key? key}) + : super(title: title, key: key) { + ByteAccumulatorSink sink = ByteAccumulatorSink(); + + test('提供对连接字节的访问', () { + sink = ByteAccumulatorSink(); + expect(sink.bytes.isEmpty, sink.bytes.isEmpty); + + sink.add([1, 2, 3]); + expect(sink.bytes, ([1, 2, 3])); + + sink.addSlice([4, 5, 6, 7, 8], 1, 4, false); + expect(sink.bytes, ([1, 2, 3, 5, 6, 7])); + }); + + test('clear()清除字节', () { + sink.add([1, 2, 3]); + expect(sink.bytes, ([1, 2, 3])); + + sink.clear(); + expect(sink.bytes.isEmpty, sink.bytes.isEmpty); + + sink.add([4, 5, 6]); + expect(sink.bytes, ([4, 5, 6])); + }); + + test('ByteAccumulatorSink 是否关闭', () { + sink = ByteAccumulatorSink(); + expect(sink.isClosed, false); + sink.close(); + expect(sink.isClosed, true); + }); + + test('指示接收器是否通过addSlice关闭', () { + sink = ByteAccumulatorSink(); + expect(sink.isClosed, false); + sink.addSlice([], 0, 0, true); + expect(sink.isClosed, true); + }); + + test("不允许在close()之后调用add(),此处应为x", () { + sink.close(); + sink.add([1]); + expect(() => sink.add([1]), () => sink.add([1])); + }); + + test("不允许在close()之后调用addSlice(),此处应为x", () { + sink.close(); + sink.addSlice([], 0, 0, false); + expect(() => sink.addSlice([], 0, 0, false), + () => sink.addSlice([], 0, 0, false)); + }); + } +} diff --git a/ohos/test_convert/lib/src/codepage_test.dart b/ohos/test_convert/lib/src/codepage_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1d81552c8e0daf10adefb4165e4e70d7408b7065 --- /dev/null +++ b/ohos/test_convert/lib/src/codepage_test.dart @@ -0,0 +1,94 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:typed_data'; + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class CodepageTestPage extends TestPage { + CodepageTestPage(String title, {Key? key}) : super(title: title, key: key) { + var bytes = Uint8List.fromList([for (var i = 0; i < 256; i++) i]); + for (var cp in [ + latin2, + latin3, + latin4, + latin5, + latin6, + latin7, + latin8, + latin9, + latin10, + latinCyrillic, + latinGreek, + latinHebrew, + latinThai, + latinArabic + ]) { + test('${cp.name} 解码', () { + // All ASCII compatible. + for (var byte = 0x20; byte < 0x7f; byte++) { + expect(cp[byte], byte); + } + // Maps both directions. + for (var byte = 0; byte < 256; byte++) { + var char = cp[byte]; + if (char != 0xFFFD) { + var string = String.fromCharCode(char); + expect(cp.encode(string), [byte]); + expect(cp.decode([byte]), string); + } + } + expect(() => cp.decode([0xfffd]), () => cp.decode([0xfffd])); + // Decode works like operator[]. + expect(cp.decode(bytes, allowInvalid: true), + String.fromCharCodes([for (var i = 0; i < 256; i++) cp[i]])); + }); + } + test('latin-2 编解码', () { + // Data from http://www.columbia.edu/kermit/latin2.html + var latin2text = '\xa0Ą˘Ł¤ĽŚ§¨ŠŞŤŹ\xadŽŻ°ą˛ł´ľśˇ¸šşťź˝žżŔÁÂĂÄĹĆÇČÉĘËĚÍÎĎĐŃŇ' + 'ÓÔŐÖ×ŘŮÚŰÜÝŢßŕáâăäĺćçčéęëěíîďđńňóôőö÷řůúűüýţ˙'; + expect(latin2.decode(latin2.encode(latin2text)), latin2text); + }); + + test('latin-3 编解码', () { + // Data from http://www.columbia.edu/kermit/latin3.html + var latin2text = '\xa0Ħ˘£¤\u{FFFD}Ĥ§¨İŞĞĴ\xad\u{FFFD}ݰħ²³´µĥ·¸ışğĵ½' + '\u{FFFD}żÀÁÂ\u{FFFD}ÄĊĈÇÈÉÊËÌÍÎÏ\u{FFFD}ÑÒÓÔĠÖ×ĜÙÚÛÜŬŜßàáâ' + '\u{FFFD}äċĉçèéêëìíîï\u{FFFD}ñòóôġö÷ĝùúûüŭŝ˙'; + var encoded = latin3.encode(latin2text, invalidCharacter: 0); + var decoded = latin3.decode(encoded, allowInvalid: true); + expect(decoded, latin2text); + }); + + test('自定义字符测试', () { + var cp = CodePage('custom', "ABCDEF${"\uFFFD" * 250}"); + var result = cp.encode('BADCAFE'); + expect(result, [1, 0, 3, 2, 0, 5, 4]); + expect(() => cp.encode('GAD'), () => cp.encode('GAD')); + expect(cp.encode('GAD', invalidCharacter: 0x3F), [0x3F, 0, 3]); + expect(cp.decode([1, 0, 3, 2, 0, 5, 4]), 'BADCAFE'); + expect(() => cp.decode([6, 1, 255]), () => cp.decode([6, 1, 255])); + expect(cp.decode([6, 1, 255], allowInvalid: true), '\u{FFFD}B\u{FFFD}'); + }); +} +} \ No newline at end of file diff --git a/ohos/test_convert/lib/src/fixed_datetime_formatter_test.dart b/ohos/test_convert/lib/src/fixed_datetime_formatter_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..35bff0be542ebab14530b4e9ea10d67f521878b3 --- /dev/null +++ b/ohos/test_convert/lib/src/fixed_datetime_formatter_test.dart @@ -0,0 +1,243 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:convert/src/fixed_datetime_formatter.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class FixedDatetimeFormatterTestPage extends TestPage { + FixedDatetimeFormatterTestPage(String title, {Key? key}) + : super(title: title, key: key) { + var noFractionalSeconds = DateTime.utc(0); + // Testing `decode`. + test('仅分析年份', () { + var time = FixedDateTimeFormatter('YYYY').decode('1996'); + expect(time, DateTime.utc(1996)); + }); + test('忽略转义字符', () { + var time = FixedDateTimeFormatter('YYYY kiwi MM').decode('1996 rnad 01'); + expect(time, DateTime.utc(1996)); + }); + test('解析两年投掷', () { + expect(() => FixedDateTimeFormatter('YYYY YYYY'), + () => FixedDateTimeFormatter('YYYY YYYY')); + }); + test('解析年份和世纪', () { + var time = FixedDateTimeFormatter('CCYY').decode('1996'); + expect(time, DateTime.utc(1996)); + }); + test('解析年份、十年和世纪', () { + var time = FixedDateTimeFormatter('CCEY').decode('1996'); + expect(time, DateTime.utc(1996)); + }); + test('解析年、世纪、月', () { + var time = FixedDateTimeFormatter('CCYY MM').decode('1996 04'); + expect(time, DateTime.utc(1996, 4)); + }); + test('解析年、世纪、月、日', () { + var time = FixedDateTimeFormatter('CCYY MM-DD').decode('1996 04-25'); + expect(time, DateTime.utc(1996, 4, 25)); + }); + test('解析年、世纪、月、日、小时、分钟、秒', () { + var time = FixedDateTimeFormatter('CCYY MM-DD hh:mm:ss') + .decode('1996 04-25 05:03:22'); + expect(time, DateTime.utc(1996, 4, 25, 5, 3, 22)); + }); + test('分析YYYYMMDhhmmssSSS', () { + var time = FixedDateTimeFormatter('YYYYMMDDhhmmssSSS') + .decode('19960425050322533'); + expect(time, DateTime.utc(1996, 4, 25, 5, 3, 22, 533)); + }); + test('解析S 1/10秒', () { + var time = FixedDateTimeFormatter('S').decode('1'); + expect(time, noFractionalSeconds.add(const Duration(milliseconds: 100))); + }); + test('解析SS 1/100秒', () { + var time = FixedDateTimeFormatter('SS').decode('01'); + expect(time, noFractionalSeconds.add(const Duration(milliseconds: 10))); + }); + test('解析SSS一毫秒', () { + var time = FixedDateTimeFormatter('SSS').decode('001'); + expect(time, noFractionalSeconds.add(const Duration(milliseconds: 1))); + }); + test('解析SSSSSS一微秒', () { + var time = FixedDateTimeFormatter('SSSSSS').decode('000001'); + expect(time, noFractionalSeconds.add(const Duration(microseconds: 1))); + }); + test('解析SSSSSS一毫秒', () { + var time = FixedDateTimeFormatter('SSSSSS').decode('001000'); + expect(time, noFractionalSeconds.add(const Duration(milliseconds: 1))); + }); + test('解析SSSSSS一毫秒和一微秒', () { + var time = FixedDateTimeFormatter('SSSSSS').decode('001001'); + expect( + time, + noFractionalSeconds.add(const Duration( + milliseconds: 1, + microseconds: 1, + ))); + }); + test('解析SSSSSS一秒零一微秒', () { + var time = FixedDateTimeFormatter('ssSSSSSS').decode('01000001'); + expect( + time, + noFractionalSeconds.add(const Duration( + seconds: 1, + microseconds: 1, + ))); + }); + test('7 S 抛出异常', () { + expect( + FixedDateTimeFormatter('S' * 7), + FixedDateTimeFormatter('S' * 7), + ); + }); + test('10 Y 抛出异常', () { + expect( + FixedDateTimeFormatter('Y' * 10), + FixedDateTimeFormatter('Y' * 10), + ); + }); + test('Parse hex year 抛出异常', () { + expect( + FixedDateTimeFormatter('YYYY').decode('0xAB'), + FixedDateTimeFormatter('YYYY').decode('0xAB'), + ); + }); + // Testing `tryDecode`. + test('尝试分析年份', () { + var time = FixedDateTimeFormatter('YYYY').tryDecode('1996'); + expect(time, DateTime.utc(1996)); + }); + test('尝试解析十六进制年份返回null', () { + var time = FixedDateTimeFormatter('YYYY').tryDecode('0xAB'); + expect(time, null); + }); + test('尝试分析无效返回null', () { + var time = FixedDateTimeFormatter('YYYY').tryDecode('1x96'); + expect(time, null); + }); + // Testing `encode`. + test('格式简单', () { + var time = DateTime.utc(1996); + expect( + FixedDateTimeFormatter('YYYY kiwi MM').encode(time), '1996 kiwi 01'); + }); + test('格式YYYYMMDhhmmss', () { + var time = DateTime.utc(1996, 4, 25, 5, 3, 22); + expect( + FixedDateTimeFormatter('YYYYMMDDhhmmss').encode(time), + '19960425050322', + ); + }); + test('CCEY-MM格式', () { + var str = FixedDateTimeFormatter('CCEY-MM').encode(DateTime.utc(1996, 4)); + expect(str, '1996-04'); + }); + test('XCCEY-MMX格式', () { + var str = + FixedDateTimeFormatter('XCCEY-MMX').encode(DateTime.utc(1996, 4)); + expect(str, 'X1996-04X'); + }); + test('格式S 1/10秒', () { + var str = FixedDateTimeFormatter('S') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 100))); + expect(str, '1'); + }); + test('格式SS 1/100秒', () { + var str = FixedDateTimeFormatter('SS') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 10))); + expect(str, '01'); + }); + test('格式SSS 1/100秒', () { + var str = FixedDateTimeFormatter('SSS') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 10))); + expect(str, '010'); + }); + test('无分数SSSS格式', () { + var str = FixedDateTimeFormatter('SSSS').encode(noFractionalSeconds); + expect(str, '0000'); + }); + test('无分数SSSSSS格式', () { + var str = FixedDateTimeFormatter('SSSSSS').encode(noFractionalSeconds); + expect(str, '000000'); + }); + test('格式化SSSS 1/10秒', () { + var str = FixedDateTimeFormatter('SSSS') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 100))); + expect(str, '1000'); + }); + test('格式SSSS 1/100秒', () { + var str = FixedDateTimeFormatter('SSSS') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 10))); + expect(str, '0100'); + }); + test('格式化SSSS一毫秒', () { + var str = FixedDateTimeFormatter('SSSS') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 1))); + expect(str, '0010'); + }); + test('格式化SSSSSS一微秒格式化SSSSSS一微秒', () { + var str = FixedDateTimeFormatter('SSSSSS') + .encode(DateTime.utc(0, 1, 1, 0, 0, 0, 0, 1)); + expect(str, '000001'); + }); + test('格式化SSSSSS一毫秒和一微秒', () { + var dateTime = noFractionalSeconds.add(const Duration( + milliseconds: 1, + microseconds: 1, + )); + var str = FixedDateTimeFormatter('SSSSSS').encode(dateTime); + expect(str, '001001'); + }); + test('格式化SSSSSS 0一微秒', () { + var str = FixedDateTimeFormatter('SSSSSS0') + .encode(noFractionalSeconds.add(const Duration(microseconds: 1))); + expect(str, '0000010'); + }); + test('格式SSS 0 1/10秒', () { + var str = FixedDateTimeFormatter('SSSSSS0') + .encode(noFractionalSeconds.add(const Duration(milliseconds: 100))); + expect(str, '1000000'); + }); + test('解析ssSSSSSS一秒零一微秒', () { + var dateTime = noFractionalSeconds.add(const Duration( + seconds: 1, + microseconds: 1, + )); + var str = FixedDateTimeFormatter('ssSSSSSS').encode(dateTime); + expect(str, '01000001'); + }); + test('解析ssSSSSSS0一秒零一微秒', () { + var dateTime = noFractionalSeconds.add(const Duration( + seconds: 1, + microseconds: 1, + )); + var str = FixedDateTimeFormatter('ssSSSSSS0').encode(dateTime); + expect(str, '010000010'); + }); + test('分析负年份引发错误', () { + expect( + FixedDateTimeFormatter('YYYY').encode(DateTime(-1)), + FixedDateTimeFormatter('YYYY').encode(DateTime(-1)), + ); + }); + } +} diff --git a/ohos/test_convert/lib/src/hex_test.dart b/ohos/test_convert/lib/src/hex_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ed8a5a4b255c541d028b1827d1c29d7701dac32b --- /dev/null +++ b/ohos/test_convert/lib/src/hex_test.dart @@ -0,0 +1,269 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class HexTestPage extends TestPage { + HexTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('encoder', () { + test('将字节数组转换为十六进制', () { + expect(hex.encode([0x1a, 0xb2, 0x3c, 0xd4]), ('1ab23cd4')); + expect(hex.encode([0x00, 0x01, 0xfe, 0xff]), ('0001feff')); + }); + + group('with chunked conversion', () { + test('将字节数组转换为十六进制', () { + var results = []; + var controller = StreamController(sync: true); + controller.stream.listen(results.add); + var sink = hex.encoder.startChunkedConversion(controller.sink); + + sink.add([0x1a, 0xb2, 0x3c, 0xd4]); + expect(results, (['1ab23cd4'])); + + sink.add([0x00, 0x01, 0xfe, 0xff]); + expect(results, (['1ab23cd4', '0001feff'])); + }); + + test('处理空列表和单字节列表', () { + var results = []; + var controller = StreamController(sync: true); + controller.stream.listen(results.add); + var sink = hex.encoder.startChunkedConversion(controller.sink); + + sink.add([]); + expect(results, ([''])); + + sink.add([0x00]); + expect(results, (['', '00'])); + + sink.add([]); + expect(results, (['', '00', ''])); + }); + }); + + test('拒绝非字节', () { + expect(() => hex.encode([0x100]), () => hex.encode([0x100])); + + var sink = + hex.encoder.startChunkedConversion(StreamController(sync: true)); + expect(() => sink.add([0x100]), () => sink.add([0x100])); + }); + }); + + group('decoder', () { + test('将十六进制数组转换为字节数组', () { + expect(hex.decode('1ab23cd4'), ([0x1a, 0xb2, 0x3c, 0xd4])); + expect(hex.decode('0001feff'), ([0x00, 0x01, 0xfe, 0xff])); + }); + + test('支持大写字母', () { + expect( + hex.decode('0123456789ABCDEFabcdef'), + ([ + 0x01, + 0x23, + 0x45, + 0x67, + 0x89, + 0xab, + 0xcd, + 0xef, + 0xab, + 0xcd, + 0xef + ])); + }); + + group('with chunked conversion', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + + + + test('将十六进制数组转换为字节数组', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + + sink.add('1ab23cd4'); + expect( + results, + ([ + [0x1a, 0xb2, 0x3c, 0xd4] + ])); + + sink.add('0001feff'); + expect( + results, + ([ + [0x1a, 0xb2, 0x3c, 0xd4], + [0x00, 0x01, 0xfe, 0xff] + ])); + }); + + test('支持在块之间拆分尾随数字', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + + sink.add('1ab23'); + expect( + results, + ([ + [0x1a, 0xb2] + ])); + + sink.add('cd'); + expect( + results, + ([ + [0x1a, 0xb2], + [0x3c] + ])); + + sink.add('40001'); + expect( + results, + ([ + [0x1a, 0xb2], + [0x3c], + [0xd4, 0x00, 0x01] + ])); + + sink.add('feff'); + expect( + results, + ([ + [0x1a, 0xb2], + [0x3c], + [0xd4, 0x00, 0x01], + [0xfe, 0xff] + ])); + }); + + test('支持空字符串', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + + sink.add(''); + expect(results.isEmpty, results.isEmpty); + + sink.add('0'); + expect(results, ([[]])); + + sink.add(''); + expect(results, ([[]])); + + sink.add('0'); + expect( + results, + ([ + [], + [0x00] + ])); + + sink.add(''); + expect( + results, + ([ + [], + [0x00] + ])); + }); + + test('拒绝在close()中检测到的奇数长度', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + + sink.add('1ab23'); + expect( + results, + ([ + [0x1a, 0xb2] + ])); + expect(() => sink.close(), () => sink.close()); + }); + + test('拒绝在addSlice()中检测到的奇数长度', () { + var controller = StreamController>(sync: true); + List> results= []; + controller.stream.listen(results.add); + + StringConversionSink sink= hex.decoder.startChunkedConversion(controller.sink); + sink.addSlice('1ab23cd', 0, 5, false); + expect( + results, + ([ + [0x1a, 0xb2] + ])); + + expect( + () => sink.addSlice('1ab23cd', 5, 7, true), () => sink.addSlice('1ab23cd', 5, 7, true)); + }); + }); + + group('rejects non-hex character', () { + for (var char in [ + 'g', + 'G', + '/', + ':', + '@', + '`', + '\x00', + '\u0141', + '\u{10041}' + ]) { + test('"$char"', () { + expect(() => hex.decode('a$char'), () => hex.decode('a$char')); + expect(() => hex.decode('${char}a'), () => hex.decode('${char}a')); + + var sink = + hex.decoder.startChunkedConversion(StreamController(sync: true)); + expect(() => sink.add(char), () => sink.add(char)); + }); + } + }); + + test('拒绝convert()中检测到的奇数长度', () { + expect(() => hex.decode('1ab23cd'), () => hex.decode('1ab23cd')); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_convert/lib/src/identity_codec_test.dart b/ohos/test_convert/lib/src/identity_codec_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4c07e1caf7d80e16411061269d3f206a4559adca --- /dev/null +++ b/ohos/test_convert/lib/src/identity_codec_test.dart @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:convert'; +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class IdentityCodecTestPage extends TestPage { + IdentityCodecTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('IdentityCodec', () { + test('编码', () { + const codec = IdentityCodec(); + expect(codec.encode('hello-world'), ('hello-world')); + }); + + test('解码', () { + const codec = IdentityCodec(); + expect(codec.decode('hello-world'), ('hello-world')); + }); + + test('IdentityCodec.fuse()', () { + const stringCodec = IdentityCodec(); + final utf8Strings = stringCodec.fuse(utf8); + expect(utf8Strings, (utf8)); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_convert/lib/src/percent_test.dart b/ohos/test_convert/lib/src/percent_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..eb1c1a3a4fb52b9a9ca4768108c48167f8ecd1a9 --- /dev/null +++ b/ohos/test_convert/lib/src/percent_test.dart @@ -0,0 +1,294 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:convert'; + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class PercentTestPage extends TestPage { + PercentTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('encoder', () { + test("不对未保留的字符进行百分比编码", () { + var safeChars = 'abcdefghijklmnopqrstuvwxyz' + 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + '0123456789-._~'; + expect(percent.encode([...safeChars.codeUnits]), (safeChars)); + }); + + test('百分比编码保留的ASCII字符', () { + expect(percent.encode([...' `{@[,/^}\x7f\x00%'.codeUnits]), ('%20%60%7B%40%5B%2C%2F%5E%7D%7F%00%25')); + }); + + test('百分比编码非ASCII字符', () { + expect(percent.encode([0x80, 0xFF]), ('%80%FF')); + }); + + test('混合编码字符和未编码字符', () { + expect(percent.encode([...'a+b=\x80'.codeUnits]), ('a%2Bb%3D%80')); + }); + + group('with chunked conversion', () { + test('百分比编码字节数组', () { + var results = []; + var controller = StreamController(sync: true); + controller.stream.listen(results.add); + var sink = percent.encoder.startChunkedConversion(controller.sink); + + sink.add([...'a+b=\x80'.codeUnits]); + expect(results, (['a%2Bb%3D%80'])); + + sink.add([0x00, 0x01, 0xfe, 0xff]); + expect(results, (['a%2Bb%3D%80', '%00%01%FE%FF'])); + }); + + test('处理空列表和单字节列表', () { + var results = []; + var controller = StreamController(sync: true); + controller.stream.listen(results.add); + var sink = percent.encoder.startChunkedConversion(controller.sink); + + sink.add([]); + expect(results, ([''])); + + sink.add([0x00]); + expect(results, (['', '%00'])); + + sink.add([]); + expect(results, (['', '%00', ''])); + }); + }); + + test('拒绝非字节', () { + expect(() => percent.encode([0x100]), () => percent.encode([0x100])); + + var sink = percent.encoder.startChunkedConversion(StreamController(sync: true)); + expect(() => sink.add([0x100]), () => sink.add([0x100])); + }); + }); + + group('decoder', () { + test('将百分比编码字符串转换为字节数组', () { + expect(percent.decode('a%2Bb%3D%801'), ([...'a+b=\x801'.codeUnits])); + }); + + test('支持小写字母', () { + expect(percent.decode('a%2bb%3d%80'), ([...'a+b=\x80'.codeUnits])); + }); + + test('支持更激进的编码', () { + expect(percent.decode('%61%2E%5A'), ([...'a.Z'.codeUnits])); + }); + + test('支持攻击性较小的编码', () { + var chars = ' `{@[,/^}\x7F\x00'; + expect(percent.decode(chars), ([...chars.codeUnits])); + }); + + group('with chunked conversion', () { + var controller = StreamController>(sync: true); + List> results = []; + StringConversionSink sink = percent.decoder.startChunkedConversion(controller.sink); + + controller.stream.listen(results.add); + + test('将百分比转换为字节数组', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.add('a%2Bb%3D%801'); + print(results); + expect( + results, + ([ + [...'a+b=\x801'.codeUnits] + ])); + + sink.add('%00%01%FE%FF'); + expect( + results, + ([ + [...'a+b=\x801'.codeUnits], + [0x00, 0x01, 0xfe, 0xff] + ])); + }); + + test('支持尾随百分比和数字在块之间拆分', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.add('ab%'); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + + sink.add('2'); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + + sink.add('0cd%2'); + expect( + results, + ([ + [...'ab'.codeUnits], + [...' cd'.codeUnits] + ])); + + sink.add('0'); + expect( + results, + ([ + [...'ab'.codeUnits], + [...' cd'.codeUnits], + [...' '.codeUnits] + ])); + }); + + test('支持空字符串', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.add(''); + expect(results.isEmpty, results.isEmpty); + + sink.add('%'); + expect(results, ([[]])); + + sink.add(''); + expect(results, ([[]])); + + sink.add('2'); + expect(results, ([[]])); + + sink.add(''); + expect(results, ([[]])); + + sink.add('0'); + expect( + results, + ([ + [], + [0x20] + ])); + }); + + test('拒绝在close()中检测到的悬挂%', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.add('ab%'); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + expect(() => sink.close(), () => sink.close()); + }); + + test('拒绝在close()中检测到的悬空数字', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.add('ab%2'); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + expect(() => sink.close(), () => sink.close()); + }); + + test('在addSlice()中检测到拒绝挂起%', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.addSlice('ab%', 0, 3, false); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + + expect(() => sink.addSlice('ab%', 0, 3, true), () => sink.addSlice('ab%', 0, 3, true)); + }); + + test('拒绝在addSlice()中检测到的危险数字', () { + results = []; + var controller = StreamController>(sync: true); + controller.stream.listen(results.add); + sink = percent.decoder.startChunkedConversion(controller.sink); + + sink.addSlice('ab%2', 0, 3, false); + expect( + results, + ([ + [...'ab'.codeUnits] + ])); + + expect(() => sink.addSlice('ab%2', 0, 3, true), () => sink.addSlice('ab%2', 0, 3, true)); + }); + }); + + group('拒绝非ASCII字符', () { + for (var char in ['\u0141', '\u{10041}']) { + test('"$char"', () { + expect(() => percent.decode('a$char'), () => percent.decode('a$char')); + expect(() => percent.decode('${char}a'), () => percent.decode('${char}a')); + + var sink = percent.decoder.startChunkedConversion(StreamController(sync: true)); + expect(() => sink.add(char), () => sink.add(char)); + }); + } + }); + + test('拒绝百分比后跟非十六进制', () { + expect(() => percent.decode('%z2'), () => percent.decode('%z2')); + expect(() => percent.decode('%2z'), () => percent.decode('%2z')); + }); + + test('拒绝convert()中检测到的悬挂%', () { + expect(() => percent.decode('ab%'), () => percent.decode('ab%')); + }); + + test('拒绝convert()中检测到的悬空数字', () { + expect(() => percent.decode('ab%2'), () => percent.decode('ab%2')); + }); + }); + } +} diff --git a/ohos/test_convert/lib/src/string_accumulator_sink_test.dart b/ohos/test_convert/lib/src/string_accumulator_sink_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4ad05a79b6e660f25e546db7e9357f2b1e50cff1 --- /dev/null +++ b/ohos/test_convert/lib/src/string_accumulator_sink_test.dart @@ -0,0 +1,78 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'package:convert/convert.dart'; +import 'package:flutter/cupertino.dart'; + +import '../common/test_page.dart'; + +class StringAccumulatorSinkTestPage extends TestPage { + StringAccumulatorSinkTestPage(String title, {Key? key}) + : super(title: title, key: key) { + StringAccumulatorSink sink = StringAccumulatorSink(); + + test('提供对连接字符串的访问', () { + sink = StringAccumulatorSink(); + expect(sink.string.isEmpty, sink.string.isEmpty); + + sink.add('foo'); + expect(sink.string, ('foo')); + + sink.addSlice(' bar baz', 1, 4, false); + expect(sink.string, ('foobar')); + }); + + test('clear()清除字符串', () { + sink = StringAccumulatorSink(); + sink.add('foo'); + expect(sink.string, ('foo')); + + sink.clear(); + expect(sink.string.isEmpty, sink.string.isEmpty); + + sink.add('bar'); + expect(sink.string, ('bar')); + }); + + test('指示sink是否关闭', () { + expect(sink.isClosed, false); + sink.close(); + expect(sink.isClosed, true); + }); + + test('指示接收器是否通过addSlice关闭,此处应为x', () { + expect(sink.isClosed, false); + sink.addSlice('', 0, 0, true); + expect(sink.isClosed, true); + }); + + test("不允许在close()之后调用add(),此处应为x", () { + sink.close(); + sink.add('x'); + expect(()=>sink.add('x'), () => sink.add('x')); + }); + + test("不允许在close()之后调用addSlice(),此处应为x", () { + sink.close(); + sink.addSlice('', 0, 0, false); + expect(() => sink.addSlice('', 0, 0, false), + () => sink.addSlice('', 0, 0, false)); + }); + } +} diff --git a/ohos/test_convert/ohos/.gitignore b/ohos/test_convert/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_convert/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_convert/ohos/AppScope/app.json5 b/ohos/test_convert/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4deeb2624b6b2e94ec840b54e83ceae4167afbed --- /dev/null +++ b/ohos/test_convert/ohos/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "com.example.test_convert", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_convert/ohos/AppScope/resources/base/element/string.json b/ohos/test_convert/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..d33c3f897811d5bfeff10d21d9461695244e4344 --- /dev/null +++ b/ohos/test_convert/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_convert" + } + ] +} diff --git a/ohos/test_convert/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_convert/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_convert/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_convert/ohos/build-profile.json5 b/ohos/test_convert/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f5a8d344e8e04ce0cc1e5a642fe2051a23b643c0 --- /dev/null +++ b/ohos/test_convert/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_convert.cer", + "storePassword": "0000001A7FD2E3A417977731A244C97BB567FED7F469D8176B1914B543C8A896D88A1B3C39C0528AA149", + "keyAlias": "debugKey", + "keyPassword": "0000001AA78706D5665C382F13889D3C5D879B2D3CC963603671ECA4FC26B06D6C8239251AC191E5AB0A", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_convert.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_convert.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_convert/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_convert/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_convert/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_convert/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_convert/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_convert/ohos/dependencies/rollup.tgz b/ohos/test_convert/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_convert/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_convert/ohos/dta/icudtl.dat b/ohos/test_convert/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_convert/ohos/dta/icudtl.dat differ diff --git a/ohos/test_convert/ohos/entry/.gitignore b/ohos/test_convert/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_convert/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/build-profile.json5 b/ohos/test_convert/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_convert/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/hvigorfile.ts b/ohos/test_convert/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_convert/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_convert/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_convert/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_convert/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_convert/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_convert/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_convert/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_convert/ohos/entry/oh-package.json5 b/ohos/test_convert/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_convert/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_convert/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_convert/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_convert/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_convert/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/main/module.json5 b/ohos/test_convert/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_convert/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_convert/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_convert/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_convert/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_convert/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_convert/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_convert/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_convert/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_convert/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/module.json5 b/ohos/test_convert/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_convert/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_convert/ohos/har/flutter_embedding.har b/ohos/test_convert/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_convert/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_convert/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_convert/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_convert/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_convert/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_convert/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_convert/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_convert/ohos/har/flutter_embedding.har.release.10 b/ohos/test_convert/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_convert/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_convert/ohos/har/flutter_embedding.har.release.9 b/ohos/test_convert/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_convert/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_convert/ohos/har/libflutter.so.debug.10 b/ohos/test_convert/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_convert/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_convert/ohos/har/libflutter.so.release.10 b/ohos/test_convert/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_convert/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_convert/ohos/hvigor/hvigor-config.json5 b/ohos/test_convert/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_convert/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_convert/ohos/hvigor/hvigor-wrapper.js b/ohos/test_convert/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_convert/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_convert/ohos/hvigorfile.ts b/ohos/test_convert/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_convert/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_convert/ohos/hvigorw b/ohos/test_convert/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..b47d8e0bbf6b056bd7edc05d499f77169bc8039c --- /dev/null +++ b/ohos/test_convert/ohos/hvigorw @@ -0,0 +1,77 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_convert/ohos/hvigorw.bat b/ohos/test_convert/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..af276bb8570c1aa3316570bafc01660bdb5c387b --- /dev/null +++ b/ohos/test_convert/ohos/hvigorw.bat @@ -0,0 +1,80 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_convert/ohos/oh-package-lock.json5 b/ohos/test_convert/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..aee107aa327bfeffa65cb553c695c76ffdd0bff6 --- /dev/null +++ b/ohos/test_convert/ohos/oh-package-lock.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_convert/ohos/oh-package.json5 b/ohos/test_convert/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4251fb9b0d09b976a22b988ce7604f050bd28ff7 --- /dev/null +++ b/ohos/test_convert/ohos/oh-package.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_convert/pubspec.yaml b/ohos/test_convert/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..d7fae0e9eff4c9b2b5e67acfc333a6873f908057 --- /dev/null +++ b/ohos/test_convert/pubspec.yaml @@ -0,0 +1,32 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_convert +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + convert: 3.1.1 +dev_dependencies: + benchmark_harness: ^2.2.0 + lints: ^2.0.0 + test: ^1.17.0 +flutter: + uses-material-design: true \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/.gitignore b/ohos/test_flutter_cache_manager/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_flutter_cache_manager/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_flutter_cache_manager/.metadata b/ohos/test_flutter_cache_manager/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_flutter_cache_manager/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_flutter_cache_manager/README.md b/ohos/test_flutter_cache_manager/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/analysis_options.yaml b/ohos/test_flutter_cache_manager/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_flutter_cache_manager/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_flutter_cache_manager/assets/image-120.png b/ohos/test_flutter_cache_manager/assets/image-120.png new file mode 100644 index 0000000000000000000000000000000000000000..a02e94a16e1ef5f9db866407d36541c1aa0d0f47 Binary files /dev/null and b/ohos/test_flutter_cache_manager/assets/image-120.png differ diff --git a/ohos/test_flutter_cache_manager/lib/common/base_page.dart b/ohos/test_flutter_cache_manager/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/common/item_widget.dart b/ohos/test_flutter_cache_manager/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/common/main_item_widget.dart b/ohos/test_flutter_cache_manager/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/common/test_model_app.dart b/ohos/test_flutter_cache_manager/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/common/test_page.dart b/ohos/test_flutter_cache_manager/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_flutter_cache_manager/lib/common/test_route.dart b/ohos/test_flutter_cache_manager/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_flutter_cache_manager/lib/main.dart b/ohos/test_flutter_cache_manager/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..0fd2db5d6a59acf1bd1f7a3ba24a5816042fdf44 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/main.dart @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:flutter/foundation.dart' show kDebugMode; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:test_flutter_cache_manager/plugin_example/download_page.dart'; +import 'package:test_flutter_cache_manager/plugin_example/input_page.dart'; +import 'package:test_flutter_cache_manager/src/cache_manager_test.dart'; +import 'package:test_flutter_cache_manager/src/cache_object_test.dart'; +import 'package:test_flutter_cache_manager/src/cache_store_test.dart'; +import 'package:test_flutter_cache_manager/src/http_file_fetcher_test.dart'; +import 'package:test_flutter_cache_manager/src/image_cache_manager_test.dart'; +import 'package:test_flutter_cache_manager/src/repositories/json_file_repository_test.dart'; +import 'package:test_flutter_cache_manager/src/repositories/migration_test.dart'; +import 'package:test_flutter_cache_manager/src/web_helper_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + HttpOverrides.global = GlobalHttpOverrides(); + final app = [ + MainItem('可视化ui界面', InputPage()), + MainItem('WebHelper', WebHelperTestPage('WebHelper')), + MainItem( + 'ImageCacheManager', ImageCacheManagerTestPage('ImageCacheManager')), + MainItem('HttpFileService', HttpFileServiceTestPage('HttpFileService')), + MainItem('CacheStore', CacheStoreTestPage('CacheStore')), + MainItem('CacheObject', CacheObjectTestPage('CacheObject')), + MainItem('CacheManager', CacheManagerTestPage('CacheManager')), + MainItem('Migration', MigrationTestPage('Migration')), + MainItem('JsonCacheInfoRepository', + JsonCacheInfoRepositoryTestPage('JsonCacheInfoRepository')), + ]; + + runApp(TestModelApp(appName: 'flutter_cache_manager', data: app)); +} + +class GlobalHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + // TODO: implement createHttpClient + return super.createHttpClient(context) + ..badCertificateCallback = + (X509Certificate cert, String host, int port) => true; + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/CHANGELOG.md b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/LICENSE b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..447867e0637e9624a9a7d25dc6430502aa3ec7dd --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/LICENSE @@ -0,0 +1,25 @@ +Copyright 2017, the Flutter project authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/README.md b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/build.gradle b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..9659efbc03d27a916d09b72494bb6005c66f516d --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/build.gradle @@ -0,0 +1,46 @@ +group 'io.flutter.plugins.pathprovider' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + jcenter() + } + + dependencies { + classpath 'com.android.tools.build:gradle:3.3.0' + } +} + +rootProject.allprojects { + repositories { + google() + jcenter() + } +} + +apply plugin: 'com.android.library' + +android { + compileSdkVersion 29 + + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } + android { + compileOptions { + sourceCompatibility 1.8 + targetCompatibility 1.8 + } + } +} + +dependencies { + implementation 'androidx.annotation:annotation:1.1.0' + implementation 'com.google.guava:guava:28.1-android' + testImplementation 'junit:junit:4.12' +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/gradle.properties b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..8bd86f6805108dec87d0be823bdb1384bec8aa19 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/gradle.properties @@ -0,0 +1 @@ +org.gradle.jvmargs=-Xmx1536M diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/settings.gradle b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..71bc90768477fb1e2bd5a2535dec5531c3986580 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'path_provider' diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..3e38a027a277fcc0c1b678b5dca0e7e62d5782b2 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/AndroidManifest.xml @@ -0,0 +1,18 @@ + + + + diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..902811dcb367ae535230ce67b6b69f83a5126b79 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/PathProviderPlugin.java @@ -0,0 +1,194 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.flutter.plugins.pathprovider; + +import android.content.Context; +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Handler; +import android.os.Looper; +import androidx.annotation.NonNull; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.SettableFuture; +import com.google.common.util.concurrent.ThreadFactoryBuilder; +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.util.PathUtils; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.Callable; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; + +public class PathProviderPlugin implements FlutterPlugin, MethodCallHandler { + + private Context context; + private MethodChannel channel; + private final Executor uiThreadExecutor = new UiThreadExecutor(); + private final Executor executor = + Executors.newSingleThreadExecutor( + new ThreadFactoryBuilder() + .setNameFormat("path-provider-background-%d") + .setPriority(Thread.NORM_PRIORITY) + .build()); + + public PathProviderPlugin() {} + + @SuppressWarnings("deprecation") + public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + PathProviderPlugin instance = new PathProviderPlugin(); + instance.channel = new MethodChannel(registrar.messenger(), "plugins.flutter.io/path_provider"); + instance.context = registrar.context(); + instance.channel.setMethodCallHandler(instance); + } + + @Override + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) { + channel = new MethodChannel(binding.getBinaryMessenger(), "plugins.flutter.io/path_provider"); + context = binding.getApplicationContext(); + channel.setMethodCallHandler(this); + } + + @Override + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) { + channel.setMethodCallHandler(null); + channel = null; + } + + private void executeInBackground(Callable task, Result result) { + final SettableFuture future = SettableFuture.create(); + Futures.addCallback( + future, + new FutureCallback() { + public void onSuccess(T answer) { + result.success(answer); + } + + public void onFailure(Throwable t) { + result.error(t.getClass().getName(), t.getMessage(), null); + } + }, + uiThreadExecutor); + executor.execute( + () -> { + try { + future.set(task.call()); + } catch (Throwable t) { + future.setException(t); + } + }); + } + + @Override + public void onMethodCall(MethodCall call, @NonNull Result result) { + switch (call.method) { + case "getTemporaryDirectory": + executeInBackground(() -> getPathProviderTemporaryDirectory(), result); + break; + case "getApplicationDocumentsDirectory": + executeInBackground(() -> getPathProviderApplicationDocumentsDirectory(), result); + break; + case "getStorageDirectory": + executeInBackground(() -> getPathProviderStorageDirectory(), result); + break; + case "getExternalCacheDirectories": + executeInBackground(() -> getPathProviderExternalCacheDirectories(), result); + break; + case "getExternalStorageDirectories": + final Integer type = call.argument("type"); + final String directoryName = StorageDirectoryMapper.androidType(type); + executeInBackground(() -> getPathProviderExternalStorageDirectories(directoryName), result); + break; + case "getApplicationSupportDirectory": + executeInBackground(() -> getApplicationSupportDirectory(), result); + break; + default: + result.notImplemented(); + } + } + + private String getPathProviderTemporaryDirectory() { + return context.getCacheDir().getPath(); + } + + private String getApplicationSupportDirectory() { + return PathUtils.getFilesDir(context); + } + + private String getPathProviderApplicationDocumentsDirectory() { + return PathUtils.getDataDirectory(context); + } + + private String getPathProviderStorageDirectory() { + final File dir = context.getExternalFilesDir(null); + if (dir == null) { + return null; + } + return dir.getAbsolutePath(); + } + + private List getPathProviderExternalCacheDirectories() { + final List paths = new ArrayList<>(); + + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + for (File dir : context.getExternalCacheDirs()) { + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + } else { + File dir = context.getExternalCacheDir(); + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + + return paths; + } + + private List getPathProviderExternalStorageDirectories(String type) { + final List paths = new ArrayList<>(); + + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + for (File dir : context.getExternalFilesDirs(type)) { + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + } else { + File dir = context.getExternalFilesDir(type); + if (dir != null) { + paths.add(dir.getAbsolutePath()); + } + } + + return paths; + } + + private static class UiThreadExecutor implements Executor { + private final Handler handler = new Handler(Looper.getMainLooper()); + + @Override + public void execute(Runnable command) { + handler.post(command); + } + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java new file mode 100644 index 0000000000000000000000000000000000000000..23459294300e4f91eeee552804b29f454c12716c --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/main/java/io/flutter/plugins/pathprovider/StorageDirectoryMapper.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.flutter.plugins.pathprovider; + +import android.os.Build.VERSION; +import android.os.Build.VERSION_CODES; +import android.os.Environment; + +/** Helps to map the Dart `StorageDirectory` enum to a Android system constant. */ +class StorageDirectoryMapper { + + /** + * Return a Android Environment constant for a Dart Index. + * + * @return The correct Android Environment constant or null, if the index is null. + * @throws IllegalArgumentException If `dartIndex` is not null but also not matches any known + * index. + */ + static String androidType(Integer dartIndex) throws IllegalArgumentException { + if (dartIndex == null) { + return null; + } + + switch (dartIndex) { + case 0: + return Environment.DIRECTORY_MUSIC; + case 1: + return Environment.DIRECTORY_PODCASTS; + case 2: + return Environment.DIRECTORY_RINGTONES; + case 3: + return Environment.DIRECTORY_ALARMS; + case 4: + return Environment.DIRECTORY_NOTIFICATIONS; + case 5: + return Environment.DIRECTORY_PICTURES; + case 6: + return Environment.DIRECTORY_MOVIES; + case 7: + return Environment.DIRECTORY_DOWNLOADS; + case 8: + return Environment.DIRECTORY_DCIM; + case 9: + if (VERSION.SDK_INT >= VERSION_CODES.KITKAT) { + return Environment.DIRECTORY_DOCUMENTS; + } else { + throw new IllegalArgumentException("Documents directory is unsupported."); + } + default: + throw new IllegalArgumentException("Unknown index: " + dartIndex); + } + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java new file mode 100644 index 0000000000000000000000000000000000000000..74a4e6d5169df8cf845fd1d8f35708b5625fbd50 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/android/src/test/java/io/flutter/plugins/pathprovider/StorageDirectoryMapperTest.java @@ -0,0 +1,39 @@ +package io.flutter.plugins.pathprovider; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.fail; + +import android.os.Environment; +import org.junit.Test; + +public class StorageDirectoryMapperTest { + + @org.junit.Test + public void testAndroidType_null() { + assertNull(StorageDirectoryMapper.androidType(null)); + } + + @org.junit.Test + public void testAndroidType_valid() { + assertEquals(Environment.DIRECTORY_MUSIC, StorageDirectoryMapper.androidType(0)); + assertEquals(Environment.DIRECTORY_PODCASTS, StorageDirectoryMapper.androidType(1)); + assertEquals(Environment.DIRECTORY_RINGTONES, StorageDirectoryMapper.androidType(2)); + assertEquals(Environment.DIRECTORY_ALARMS, StorageDirectoryMapper.androidType(3)); + assertEquals(Environment.DIRECTORY_NOTIFICATIONS, StorageDirectoryMapper.androidType(4)); + assertEquals(Environment.DIRECTORY_PICTURES, StorageDirectoryMapper.androidType(5)); + assertEquals(Environment.DIRECTORY_MOVIES, StorageDirectoryMapper.androidType(6)); + assertEquals(Environment.DIRECTORY_DOWNLOADS, StorageDirectoryMapper.androidType(7)); + assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(8)); + } + + @Test + public void testAndroidType_invalid() { + try { + assertEquals(Environment.DIRECTORY_DCIM, StorageDirectoryMapper.androidType(10)); + fail(); + } catch (IllegalArgumentException e) { + assertEquals("Unknown index: " + 10, e.getMessage()); + } + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Assets/.gitkeep b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Assets/.gitkeep new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h new file mode 100644 index 0000000000000000000000000000000000000000..6be117df80280a424a16000eb3b7318dd839c348 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import + +@interface FLTPathProviderPlugin : NSObject +@end diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m new file mode 100644 index 0000000000000000000000000000000000000000..8559e324ce784e630bc26784f1fb32073313981d --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/Classes/FLTPathProviderPlugin.m @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#import "FLTPathProviderPlugin.h" + +NSString* GetDirectoryOfType(NSSearchPathDirectory dir) { + NSArray* paths = NSSearchPathForDirectoriesInDomains(dir, NSUserDomainMask, YES); + return paths.firstObject; +} + +static FlutterError* getFlutterError(NSError* error) { + if (error == nil) return nil; + return [FlutterError errorWithCode:[NSString stringWithFormat:@"Error %ld", (long)error.code] + message:error.domain + details:error.localizedDescription]; +} + +@implementation FLTPathProviderPlugin + ++ (void)registerWithRegistrar:(NSObject*)registrar { + FlutterMethodChannel* channel = + [FlutterMethodChannel methodChannelWithName:@"plugins.flutter.io/path_provider" + binaryMessenger:registrar.messenger]; + [channel setMethodCallHandler:^(FlutterMethodCall* call, FlutterResult result) { + if ([@"getTemporaryDirectory" isEqualToString:call.method]) { + result([self getTemporaryDirectory]); + } else if ([@"getApplicationDocumentsDirectory" isEqualToString:call.method]) { + result([self getApplicationDocumentsDirectory]); + } else if ([@"getApplicationSupportDirectory" isEqualToString:call.method]) { + NSString* path = [self getApplicationSupportDirectory]; + + // Create the path if it doesn't exist + NSError* error; + NSFileManager* fileManager = [NSFileManager defaultManager]; + BOOL success = [fileManager createDirectoryAtPath:path + withIntermediateDirectories:YES + attributes:nil + error:&error]; + if (!success) { + result(getFlutterError(error)); + } else { + result(path); + } + } else if ([@"getLibraryDirectory" isEqualToString:call.method]) { + result([self getLibraryDirectory]); + } else { + result(FlutterMethodNotImplemented); + } + }]; +} + ++ (NSString*)getTemporaryDirectory { + return GetDirectoryOfType(NSCachesDirectory); +} + ++ (NSString*)getApplicationDocumentsDirectory { + return GetDirectoryOfType(NSDocumentDirectory); +} + ++ (NSString*)getApplicationSupportDirectory { + return GetDirectoryOfType(NSApplicationSupportDirectory); +} + ++ (NSString*)getLibraryDirectory { + return GetDirectoryOfType(NSLibraryDirectory); +} + +@end diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/path_provider.podspec b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/path_provider.podspec new file mode 100644 index 0000000000000000000000000000000000000000..151d755273485f33e74efefec3a30e5b53424891 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/ios/path_provider.podspec @@ -0,0 +1,38 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'path_provider' + s.version = '0.0.1' + s.summary = 'Flutter Path Provider' + s.description = <<-DESC +A Flutter plugin for getting commonly used locations on the filesystem. +Downloaded by pub (not CocoaPods). + DESC + s.homepage = 'https://github.com/flutter/plugins' + s.license = { :type => 'BSD', :file => '../LICENSE' } + s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } + s.source = { :http => 'https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider' } + s.documentation_url = 'https://pub.dev/packages/path_provider' + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } +end + diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/lib/path_provider.dart b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/lib/path_provider.dart new file mode 100644 index 0000000000000000000000000000000000000000..0a6b944993323ab0c7a94ca2251f58a973e23117 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/lib/path_provider.dart @@ -0,0 +1,233 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:io' show Directory, Platform; + +import 'package:flutter/foundation.dart' show kIsWeb, visibleForTesting; +import 'package:path_provider_linux/path_provider_linux.dart'; +import 'package:path_provider_windows/path_provider_windows.dart'; +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'package:path_provider_platform_interface/src/method_channel_path_provider.dart'; + +export 'package:path_provider_platform_interface/path_provider_platform_interface.dart' + show StorageDirectory; + +@visibleForTesting +@Deprecated('This is no longer necessary, and is now a no-op') +set disablePathProviderPlatformOverride(bool override) {} + +bool _manualDartRegistrationNeeded = true; + +/// An exception thrown when a directory that should always be available on +/// the current platform cannot be obtained. +class MissingPlatformDirectoryException implements Exception { + /// Creates a new exception + MissingPlatformDirectoryException(this.message, {this.details}); + + /// The explanation of the exception. + final String message; + + /// Added details, if any. + /// + /// E.g., an error object from the platform implementation. + final Object? details; + + @override + String toString() { + String detailsAddition = details == null ? '' : ': $details'; + return 'MissingPlatformDirectoryException($message)$detailsAddition'; + } +} + +PathProviderPlatform get _platform { + // This is to manually endorse Dart implementations until automatic + // registration of Dart plugins is implemented. For details see + // https://github.com/flutter/flutter/issues/52267. + if (_manualDartRegistrationNeeded) { + // Only do the initial registration if it hasn't already been overridden + // with a non-default instance. + if (!kIsWeb && PathProviderPlatform.instance is MethodChannelPathProvider) { + if (Platform.isLinux) { + PathProviderPlatform.instance = PathProviderLinux(); + } else if (Platform.isWindows) { + PathProviderPlatform.instance = PathProviderWindows(); + } + } + _manualDartRegistrationNeeded = false; + } + + return PathProviderPlatform.instance; +} + +/// Path to the temporary directory on the device that is not backed up and is +/// suitable for storing caches of downloaded files. +/// +/// Files in this directory may be cleared at any time. This does *not* return +/// a new temporary directory. Instead, the caller is responsible for creating +/// (and cleaning up) files or directories within this directory. This +/// directory is scoped to the calling application. +/// +/// On iOS, this uses the `NSCachesDirectory` API. +/// +/// On Android, this uses the `getCacheDir` API on the context. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getTemporaryDirectory() async { + final String? path = await _platform.getTemporaryPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get temporary directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may place application support +/// files. +/// +/// Use this for files you don’t want exposed to the user. Your app should not +/// use this directory for user data files. +/// +/// On iOS, this uses the `NSApplicationSupportDirectory` API. +/// If this directory does not exist, it is created automatically. +/// +/// On Android, this function uses the `getFilesDir` API on the context. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationSupportDirectory() async { + final String? path = await _platform.getApplicationSupportPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get application support directory'); + } + + return Directory(path); +} + +/// Path to the directory where application can store files that are persistent, +/// backed up, and not visible to the user, such as sqlite.db. +/// +/// On Android, this function throws an [UnsupportedError] as no equivalent +/// path exists. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory on a supported platform. +Future getLibraryDirectory() async { + final String? path = await _platform.getLibraryPath(); + if (path == null) { + throw MissingPlatformDirectoryException('Unable to get library directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may place data that is +/// user-generated, or that cannot otherwise be recreated by your application. +/// +/// On iOS, this uses the `NSDocumentDirectory` API. Consider using +/// [getApplicationSupportDirectory] instead if the data is not user-generated. +/// +/// On Android, this uses the `getDataDirectory` API on the context. Consider +/// using [getExternalStorageDirectory] instead if data is intended to be visible +/// to the user. +/// +/// Throws a `MissingPlatformDirectoryException` if the system is unable to +/// provide the directory. +Future getApplicationDocumentsDirectory() async { + final String? path = await _platform.getApplicationDocumentsPath(); + if (path == null) { + throw MissingPlatformDirectoryException( + 'Unable to get application documents directory'); + } + return Directory(path); +} + +/// Path to a directory where the application may access top level storage. +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an [UnsupportedError] as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this uses the `getExternalFilesDir(null)`. +Future getExternalStorageDirectory() async { + final String? path = await _platform.getExternalStoragePath(); + if (path == null) { + return null; + } + return Directory(path); +} + +/// Paths to directories where application specific external cache data can be +/// stored. These paths typically reside on external storage like separate +/// partitions or SD cards. Phones may have multiple storage directories +/// available. +/// +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an UnsupportedError as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this returns Context.getExternalCacheDirs() or +/// Context.getExternalCacheDir() on API levels below 19. +Future?> getExternalCacheDirectories() async { + final List? paths = await _platform.getExternalCachePaths(); + if (paths == null) { + return null; + } + + return paths.map((String path) => Directory(path)).toList(); +} + +/// Paths to directories where application specific data can be stored. +/// These paths typically reside on external storage like separate partitions +/// or SD cards. Phones may have multiple storage directories available. +/// +/// The current operating system should be determined before issuing this +/// function call, as this functionality is only available on Android. +/// +/// On iOS, this function throws an UnsupportedError as it is not possible +/// to access outside the app's sandbox. +/// +/// On Android this returns Context.getExternalFilesDirs(String type) or +/// Context.getExternalFilesDir(String type) on API levels below 19. +Future?> getExternalStorageDirectories({ + /// Optional parameter. See [StorageDirectory] for more informations on + /// how this type translates to Android storage directories. + StorageDirectory? type, +}) async { + final List? paths = + await _platform.getExternalStoragePaths(type: type); + if (paths == null) { + return null; + } + + return paths.map((String path) => Directory(path)).toList(); +} + +/// Path to the directory where downloaded files can be stored. +/// This is typically only relevant on desktop operating systems. +/// +/// On Android and on iOS, this function throws an [UnsupportedError] as no equivalent +/// path exists. +Future getDownloadsDirectory() async { + final String? path = await _platform.getDownloadsPath(); + if (path == null) { + return null; + } + return Directory(path); +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/macos/path_provider.podspec b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/macos/path_provider.podspec new file mode 100644 index 0000000000000000000000000000000000000000..9f3f01f2f8583e9ba2864c39e2833246c3b4ac00 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/macos/path_provider.podspec @@ -0,0 +1,22 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html +# +Pod::Spec.new do |s| + s.name = 'path_provider' + s.version = '0.0.1' + s.summary = 'No-op implementation of the macos path_provider to avoid build issues on macos' + s.description = <<-DESC + No-op implementation of the path_provider plugin to avoid build issues on macos. + https://github.com/flutter/flutter/issues/46618 + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/path_provider' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.public_header_files = 'Classes/**/*.h' + + s.platform = :osx + s.osx.deployment_target = '10.11' +end + diff --git a/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/pubspec.yaml b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3ae3b3ffb7d262900ad4ec78281f1651827972ae --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider-2.0.0/pubspec.yaml @@ -0,0 +1,61 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: path_provider +description: Flutter plugin for getting commonly used locations on host platform file systems, such as the temp and app data directories. +homepage: https://github.com/flutter/plugins/tree/master/packages/path_provider/path_provider +version: 2.0.0 +publish_to: none + +flutter: + plugin: + platforms: + android: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + ios: + pluginClass: FLTPathProviderPlugin + macos: + default_package: path_provider_ohos + linux: + default_package: path_provider_ohos + windows: + default_package: path_provider_ohos + ohos: + default_package: path_provider_ohos + +dependencies: + flutter: + sdk: flutter + path_provider_platform_interface: ^2.0.0 + path_provider_macos: ^2.0.0 + path_provider_linux: ^2.0.0 + path_provider_windows: ^2.0.0 + path_provider_ohos: + path: ../path_provider_ohos +dev_dependencies: +# integration_test: +# path: ../../integration_test + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + pedantic: ^1.10.0 + plugin_platform_interface: ">=1.0.0 <3.0.0" + test: ^1.16.0 + +environment: + sdk: ">=2.12.0-259.9.beta <3.0.0" + flutter: ">=1.12.13+hotfix.5" diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/AUTHORS b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..d6a0ebb6ce1ec5f6713344bf177684cd0372cccf --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/AUTHORS @@ -0,0 +1,81 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/CHANGELOG.md b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/LICENSE b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c6823b81eb845db89cee59cbbc7ee0b0b63d86ec --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/README.md b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/messages.g.dart b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/messages.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..032f324e926ebf4328f49f0ef59adcdf19a36cc0 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/messages.g.dart @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v9.2.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum StorageDirectory { + root, + music, + podcasts, + ringtones, + alarms, + notifications, + pictures, + movies, + downloads, + dcim, + documents, +} + +class PathProviderApi { + /// Constructor for [PathProviderApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + PathProviderApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getTemporaryPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationSupportPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationDocumentsPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationCachePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getExternalStoragePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future> getExternalCachePaths() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getExternalStoragePaths( + StorageDirectory arg_directory) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_directory.index]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/path_provider_ohos.dart b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/path_provider_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..62a2051832acae8667740e017065b3c4c9bde545 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/lib/path_provider_ohos.dart @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'messages.g.dart' as messages; + +messages.StorageDirectory _convertStorageDirectory( + StorageDirectory? directory) { + switch (directory) { + case null: + return messages.StorageDirectory.root; + case StorageDirectory.music: + return messages.StorageDirectory.music; + case StorageDirectory.podcasts: + return messages.StorageDirectory.podcasts; + case StorageDirectory.ringtones: + return messages.StorageDirectory.ringtones; + case StorageDirectory.alarms: + return messages.StorageDirectory.alarms; + case StorageDirectory.notifications: + return messages.StorageDirectory.notifications; + case StorageDirectory.pictures: + return messages.StorageDirectory.pictures; + case StorageDirectory.movies: + return messages.StorageDirectory.movies; + case StorageDirectory.downloads: + return messages.StorageDirectory.downloads; + case StorageDirectory.dcim: + return messages.StorageDirectory.dcim; + case StorageDirectory.documents: + return messages.StorageDirectory.documents; + } +} + +/// The OHOS implementation of [PathProviderPlatform]. +class PathProviderOhos extends PathProviderPlatform { + final messages.PathProviderApi _api = messages.PathProviderApi(); + + /// Registers this class as the default instance of [PathProviderPlatform]. + static void registerWith() { + PathProviderPlatform.instance = PathProviderOhos(); + } + + @override + Future getTemporaryPath() { + return _api.getTemporaryPath(); + } + + @override + Future getApplicationSupportPath() { + return _api.getApplicationSupportPath(); + } + + @override + Future getLibraryPath() { + throw UnsupportedError('getLibraryPath is not supported on OHOS'); + } + + @override + Future getApplicationDocumentsPath() { + return _api.getApplicationDocumentsPath(); + } + + @override + Future getApplicationCachePath() { + return _api.getApplicationCachePath(); + } + + @override + Future getExternalStoragePath() { + return _api.getExternalStoragePath(); + } + + @override + Future?> getExternalCachePaths() async { + return (await _api.getExternalCachePaths()).cast(); + } + + @override + Future?> getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) + .cast(); + } + + @override + Future getDownloadsPath() { + throw UnsupportedError('getDownloadsPath is not supported on OHOS'); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..1e922e7e1fc28adb088df43e96d59e2e64598bf0 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json @@ -0,0 +1 @@ +{"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5":{"hashValue":"c5cbb5522de13fac82f033c7cd9b48d8","name":"app.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":226,"lastModifiedTime":1695632211627}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5":{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5":{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json":{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json":{"hashValue":"1c8e8a915a9b7f222d4cf94722d1bb42","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":491,"lastModifiedTime":1698044664928}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json":{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs":{"hashValue":"fb414dab48788ac59123df55cae63f0b","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"2a8cdcb7a112ce8f608fa4c5a8b26644","name":"flutter_ohos.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs\\flutter_ohos.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":19163432,"lastModifiedTime":1698044260416}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default":{"hashValue":"","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default","type":"directory","isSymbolicLink":false,"children":[]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources":{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default":{"hashValue":"76f5c8d078ca69ae9175830aa99a05dc","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f12d653569ed3cffc2c73dbcf141b3e7","name":"ids_map","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"fde1d32f9d3798179b3345d3d3b044a8","name":"id_defined.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":148,"lastModifiedTime":1698044665019}}]},{"hashValue":"2ed40cf3b6a0258fcf7ef0d5663211d7","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":652,"lastModifiedTime":1698044665018}},{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},{"hashValue":"98c2ba5b20a7da7409087b816f0988e8","name":"resources.index","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources.index","type":"file","isSymbolicLink":false,"fileMetaData":{"size":396,"lastModifiedTime":1698044665018}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h":{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default":{"hashValue":"93721c69ae9a43a6b6b026ce4ba28ad2","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default":{"hashValue":"de5eea44e80e5ff634766ec94c928117","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider":{"hashValue":"7190fb2c4d706ed6e0e4babda37414da","name":"path_provider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"dd38cfe42b111fd0bc58052c7bc17c51","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3a65d298f5e72b2d44c536dcdc681eab","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt":{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar":{"hashValue":"77ec3ff3075d1e1b0f77eea3593fc54a","name":"default@PackageHar","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"34bdaa94e55567ca04e39d0ddc512301","name":"build-profile.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\build-profile.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":119,"lastModifiedTime":1695632211630}},{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\libs","type":"directory","isSymbolicLink":false,"children":[]},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},{"hashValue":"ae45559de2480bc70d782647539c87a9","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d1732197995c7f8e834be72e56bec866","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default":{"hashValue":"876919e92069ce600cf972b0875777f7","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"7505492774406aa9fff80dba7d7feac7","name":"path_provider.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default\\path_provider.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":3760,"lastModifiedTime":1698044665105}}]}} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..c424f579e9642bd97516da860942f4f330a46bc7 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json @@ -0,0 +1 @@ +{":ohos:path_provider:default@PreBuild":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"apiType\",\"_value\":\"stageMode\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"codeType\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"customTypes\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceType\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isSupportOhpmProj\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"profileModuleName\",\"_value\":\"path_provider\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"sdkToolchainsComponentVersion\",\"_value\":\"4.0.0.40\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetStatusCode\",\"_value\":2,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PreBuild","_key":":ohos:path_provider:default@PreBuild","_executionId":":ohos:path_provider:default@PreBuild:1698044664739","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"isDirectory":false,"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"isDirectory":false,"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5",{"fileSnapShotHashValue":"c55207f83ac823903369a4a9dab86116"}]]},"_outputFiles":{"dataType":"Map","value":[]}},":ohos:path_provider:default@MergeProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"asanEnable\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"buildRoot\",\"_value\":\"build\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isDebug\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isHarModule\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"multiProjects\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"releaseType\",\"_value\":\"Release\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@MergeProfile","_key":":ohos:path_provider:default@MergeProfile","_executionId":":ohos:path_provider:default@MergeProfile:1698044664825","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]}},":ohos:path_provider:default@ProcessProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"arkEnable\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileMode\",\"_value\":\"esmodule\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceTypes\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"dependency\",\"_value\":\"[]\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessProfile","_key":":ohos:path_provider:default@ProcessProfile","_executionId":":ohos:path_provider:default@ProcessProfile:1698044664829","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}]]}},":ohos:path_provider:default@ProcessResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"resConfigJsonContent\",\"_value\":\"{\\\"configPath\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\process_profile\\\\\\\\default\\\\\\\\module.json\\\",\\\"packageName\\\":\\\"io.flutter.plugins.pathprovider\\\",\\\"output\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\",\\\"moduleNames\\\":\\\"path_provider\\\",\\\"ResourceTable\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\generated\\\\\\\\r\\\\\\\\default\\\\\\\\ResourceTable.h\\\"],\\\"moduleResources\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\src\\\\\\\\main\\\\\\\\resources\\\"],\\\"dependencies\\\":[],\\\"ids\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\",\\\"definedIds\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\\\\\\id_defined.json\\\"}\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessResource","_key":":ohos:path_provider:default@ProcessResource","_executionId":":ohos:path_provider:default@ProcessResource:1697686151230","_inputFiles":{"dataType":"Map","value":[]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]}},":ohos:path_provider:default@ProcessLibs":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessLibs","_key":":ohos:path_provider:default@ProcessLibs","_executionId":":ohos:path_provider:default@ProcessLibs:1698044664930","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs",{"isDirectory":true,"fileSnapShotHashValue":"fb414dab48788ac59123df55cae63f0b"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}]]}},":ohos:path_provider:default@CompileResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"TARGET_CONFIG\",\"_value\":\"{\\\"name\\\":\\\"default\\\"}\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe,-l,D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\intermediates\\\\res\\\\default\\\\resConfig.json\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@CompileResource","_key":":ohos:path_provider:default@CompileResource","_executionId":":ohos:path_provider:default@CompileResource:1698044664937","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources",{"fileSnapShotHashValue":"c8b0c1d9d5adf5ad1facbc15311568c7"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"isDirectory":false,"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default",{"isDirectory":true,"fileSnapShotHashValue":"76f5c8d078ca69ae9175830aa99a05dc"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h",{"isDirectory":false,"fileSnapShotHashValue":"d021dd9a3167074553dba4f2c5854465"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default",{"isDirectory":true,"fileSnapShotHashValue":"93721c69ae9a43a6b6b026ce4ba28ad2"}]]}},":ohos:path_provider:default@PackageHar":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"hasNativeOption\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"needCppTypes\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"harModuleJson\",\"_value\":\"D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar\\\\src\\\\main\\\\module.json5\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isOhpmProject\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"artifactType\",\"_value\":\"original\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"C:\\\\Users\\\\z30010942\\\\nodejs\\\\npm.cmd,pack\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"cwd:D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar;\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PackageHar","_key":":ohos:path_provider:default@PackageHar","_executionId":":ohos:path_provider:default@PackageHar:1698044665025","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default",{"isDirectory":true,"fileSnapShotHashValue":"de5eea44e80e5ff634766ec94c928117"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider",{"isDirectory":true,"test":{"dataType":"RegExp","value":"^(?!D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\libs|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\node_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\oh_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.cxx|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.previewer|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.hvigor|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.gitignore|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.ohpmignore).*"},"fileSnapShotHashValue":"7190fb2c4d706ed6e0e4babda37414da"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt",{"isDirectory":false,"fileSnapShotHashValue":"94cde23849d24d7b4c50116f9d63d725"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar",{"isDirectory":true,"fileSnapShotHashValue":"77ec3ff3075d1e1b0f77eea3593fc54a"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default",{"isDirectory":true,"fileSnapShotHashValue":"876919e92069ce600cf972b0875777f7"}]]}}} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json new file mode 100644 index 0000000000000000000000000000000000000000..e55e21ac77968038ea81d662bea7ef034aa7b14b --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json @@ -0,0 +1,16 @@ +{ + "totalTime": 481506500, + "moduleNum": 1, + "taskTime": { + "compileArkTS": 0, + "buildArkTS": 0, + "compileJS": 0, + "buildJS": 0, + "compileResource": 0, + "packageHap": 0, + "signHap": 0 + }, + "isIncremental": true, + "hasIncremental": false, + "isParallel": true +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json new file mode 100644 index 0000000000000000000000000000000000000000..ca06e5bb15cfd13c1535a1a9f14d0141af5ebbf3 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json @@ -0,0 +1,39 @@ +{ + "ohos-module-path_provider": { + "SELECT_TARGET": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build", + "TARGETS": { + "default": { + "SOURCE_ROOT": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main", + "RESOURCES_PATH": [ + "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources" + ], + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates", + "JS_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", + "WORKER_LOADER": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json" + }, + "BUILD_OPTION": { + "debuggable": true + } + } + } + }, + "ohos-project": { + "SELECT_PRODUCT_NAME": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build", + "BUNDLE_NAME": "io.flutter.plugins.pathprovider", + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build\\outputs\\default" + } + }, + "version": 1 +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/report/report.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/report/report.json new file mode 100644 index 0000000000000000000000000000000000000000..c812c2d046ee61ce12cbc028f21d33e82ac413a1 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/.hvigor/report/report.json @@ -0,0 +1,31 @@ +{ + "version": "1.0", + "workerIdList": [ + -1 + ], + "metrics": [ + { + "type": "build_line", + "endTime": 1699407048308, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "path_provider", + "workerId": -1, + "startTime": 1699407048307 + }, + { + "type": "build_line", + "endTime": 1699407048309, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "ohos", + "workerId": -1, + "startTime": 1699407048309 + } + ], + "workLog": [] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/app.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a95a3cd61153d08dd89daaad09a5b8066cd9a4e9 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/app.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..553ced4f7ebe2ed3fca66c4ef9637ce3ad65d12e --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "path_provider" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/build-profile.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5c1e5d53d93e28d421dca80f583fc79b3f2ef772 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.cer", + "storePassword": "0000001A14E9D3E5C4DF2ED15CED1A37B72F435E8D176F43E415FF2213D4C9C753FA62E51E4621A952A5", + "keyAlias": "debugKey", + "keyPassword": "0000001AC6F51F5DA12538489C8E00F23C111099A8622DA17D8D6B2FE7A456D4D2D21C903D3DEB198EC9", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "path_provider", + "srcPath": "./path_provider" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/rollup.tgz b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..1d60037b7da47b78525152e2b9268fe4eba9940c --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorfile.ts b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..2a70dc127d52200fc4b276b00ca6b7caa239bc62 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw @@ -0,0 +1,63 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw.bat b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..9c0bce666c29dcc3ef35dae78c7be9cafa1267ae --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/hvigorw.bat @@ -0,0 +1,79 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/local.properties b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..864e8480e5edabc3faccd6c365441bf21a0d27da --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/local.properties @@ -0,0 +1,9 @@ +# This file is automatically generated by DevEco Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file should *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# For customization when using a Version Control System, please read the header note. +nodejs.dir=C:/Users/hched/node/node-16.20.1 +hwsdk.dir=C:/Users/hched/AppData/Local/Huawei/Sdk \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package-lock.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..d0391aeca40c4c9c302f8fb57374a84a81753aae --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package-lock.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..067663753fc026633f540eb51807e129abf490aa --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/oh-package.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..989c850d90269886e5bbab58d829e9ba7257ebe1 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..96d9876920512b3c08394ae8a8fd8da4b0693c2c --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..cfbf0ed8b8d733bee4f7e27569fba585bdd00d5a --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..5f8b49917c810cfd7dbbfe7d96e06e8cf6c546e3 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "name": "path_provider", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_ohos.har" + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdb099dae873c9cd046f939e7ef58b8d72606c68 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d6d329b5a08797d077537587ae93051439a9774 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,167 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..509ef65796e39c6fc7bfadd1c938862424f7dad4 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f3517276bcfc5453175c8f9b532d32b71e7d0e76 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h new file mode 100644 index 0000000000000000000000000000000000000000..7804e730e1b4dbdb21b54729d5039a3f06d01347 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESOURCE_TABLE_H +#define RESOURCE_TABLE_H + +#include + +namespace OHOS { +const int32_t STRING_PAGE_SHOW = 0x01000000; +} +#endif \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..5fe3850329df700867f0f4692936181c9dd1f6b9 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json @@ -0,0 +1,24 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "virtualMachine": "ark9.0.0.0", + "compileMode": "esmodule", + "dependencies": [] + } +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json new file mode 100644 index 0000000000000000000000000000000000000000..384d0290daf29cee301a5271dec2824791a3d614 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json @@ -0,0 +1,10 @@ +{ + "record" : + [ + { + "id" : "0x01000000", + "name" : "page_show", + "type" : "string" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..fd826dbf47a8c5bd149d62909693a88a3df49a52 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json @@ -0,0 +1,27 @@ +{ + "app" : + { + "apiReleaseType" : "Release", + "bundleName" : "io.flutter.plugins.pathprovider", + "compileSdkType" : "HarmonyOS", + "compileSdkVersion" : "4.0.0.40", + "debug" : true, + "minAPIVersion" : 40000010, + "targetAPIVersion" : 40000010, + "versionCode" : 1000000, + "versionName" : "1.0.0" + }, + "module" : + { + "compileMode" : "esmodule", + "dependencies" : [], + "deviceTypes" : + [ + "default", + "tablet" + ], + "name" : "path_provider", + "type" : "har", + "virtualMachine" : "ark9.0.0.0" + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..272edbc65fdba3d0fd4ba496cc6c181d0aebc721 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json @@ -0,0 +1 @@ +{"configPath":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","packageName":"io.flutter.plugins.pathprovider","output":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","moduleNames":"path_provider","ResourceTable":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h"],"moduleResources":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources"],"dependencies":[],"ids":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","definedIds":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json"} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index new file mode 100644 index 0000000000000000000000000000000000000000..3b7227cd2f2eb4b8f1ecc2cd52ad2411dd6f01d9 Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..b49073ac77deb7ab1a4722ef4e4fb34a2bb57893 Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..146d26c0fbde7fade1030172bc679b8f857a7490 Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har differ diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c5b4395b50fb6f82ab488221c479b7e39129de20 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_embedding.har" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..86898f1769b5757a9956c56bbdf71250aacb49b0 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,249 @@ +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getApplicationCachePath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationCachePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationCachePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd172ef16a6bb11e51f9eed062a200065c9fcdb5 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,157 @@ +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getApplicationCachePath(): string { + return this.context.cacheDir; + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a9747412aca9d22510037a84a184dc608e4f1c48 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..12ddf6a9a9e09489e6c97403e95cb9ae8acccd9d --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b2dd4f1d969e706afc3a52f1b472ae099f65330 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/path_provider_ohos/pubspec.yaml b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..941cd6c41ec5db0c707af357b12407c8497c9594 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/path_provider_ohos/pubspec.yaml @@ -0,0 +1,46 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: path_provider_ohos +description: Ohos implementation of the path_provider plugin. +repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_ohos +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 +version: 1.0.0 + +environment: + sdk: ">=2.18.0 <4.0.0" + flutter: ">=3.3.0" + +flutter: + plugin: + implements: path_provider + platforms: + ohos: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + dartPluginClass: PathProviderOhos + +dependencies: + flutter: + sdk: flutter + path_provider_platform_interface: ^2.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + pigeon: ^9.2.4 + test: ^1.16.0 diff --git a/ohos/test_flutter_cache_manager/lib/plugin_example/download_page.dart b/ohos/test_flutter_cache_manager/lib/plugin_example/download_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..66fbeeae7954be4b28c77cc5fe73fbbeda60dfa1 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/plugin_example/download_page.dart @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +import 'file_info_widget.dart'; +import 'progress_indicator.dart' as p_i; + +/// A [Widget] showing the information about the status of the [FileResponse] +class DownloadPage extends StatelessWidget { + final Stream fileStream; + final VoidCallback downloadFile; + final VoidCallback clearCache; + final VoidCallback removeFile; + + const DownloadPage({ + required this.fileStream, + required this.downloadFile, + required this.clearCache, + required this.removeFile, + }); + + @override + Widget build(BuildContext context) { + return StreamBuilder( + stream: fileStream, + builder: (context, snapshot) { + Widget body; + final loading = !snapshot.hasData || snapshot.data is DownloadProgress; + + if (snapshot.hasError) { + body = ListTile( + title: const Text('出现错误'), + subtitle: Text(snapshot.error.toString()), + ); + } else if (loading) { + body = p_i.ProgressIndicator( + progress: snapshot.data as DownloadProgress?, + ); + } else { + body = FileInfoWidget( + fileInfo: snapshot.requireData as FileInfo, + clearCache: clearCache, + removeFile: removeFile, + ); + } + + return Scaffold( + appBar: AppBar( + title: Text('结果页'), + ), + body: body, + ); + }, + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/plugin_example/file_info_widget.dart b/ohos/test_flutter_cache_manager/lib/plugin_example/file_info_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..b11dee8d937968af31bd9bea8f4603462987ee03 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/plugin_example/file_info_widget.dart @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +/// A [Widget] showing all available information about the downloaded file +class FileInfoWidget extends StatelessWidget { + final FileInfo fileInfo; + final VoidCallback clearCache; + final VoidCallback removeFile; + + const FileInfoWidget({ + required this.clearCache, + required this.removeFile, + required this.fileInfo, + }); + + @override + Widget build(BuildContext context) { + return ListView( + children: [ + Container( + height: 200, + margin: EdgeInsets.only(top: 20, bottom: 20), + child: Image.file(fileInfo.file), + ), + ListTile( + title: const Text('远程链接'), + subtitle: Text(fileInfo.originalUrl), + ), + ListTile( + title: const Text('本地文件路径'), + subtitle: Text(fileInfo.file.path), + ), + ListTile( + title: const Text('加载来源'), + subtitle: Text(fileInfo.source.toString()), + ), + ListTile( + title: const Text('有效期至'), + subtitle: Text(fileInfo.validTill.toIso8601String()), + ), + Padding( + padding: const EdgeInsets.all(10), + child: ElevatedButton( + onPressed: clearCache, + child: const Text('清除缓存') + ), + ), + Padding( + padding: const EdgeInsets.all(10), + child: ElevatedButton( + onPressed: removeFile, + child: const Text('删除文件'), + ), + ), + ], + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/plugin_example/input_page.dart b/ohos/test_flutter_cache_manager/lib/plugin_example/input_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..04b103346e0efbc313b84ba105240f64e0d8ae01 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/plugin_example/input_page.dart @@ -0,0 +1,206 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:dio/dio.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +import 'download_page.dart'; + +/// Example [Widget] showing the functionalities of flutter_cache_manager +class InputPage extends StatefulWidget { + const InputPage(); + + @override + InputPageState createState() => InputPageState(); +} + +class InputPageState extends State { + Stream? fileStream; + + final String staticUrl = + 'http://img2.baidu.com/it/u=3902309251,2849519907&fm=253&fmt=auto&app=138&f=JPEG?w=500&h=889'; + + bool lock = false; + + String statusCode = ''; + String dioGet = ''; + + final TextEditingController controller = TextEditingController(); + + void _testDownloadFile() async { + print( + 'ohFlutter: ------------------------------------------------------------'); + + // final storageStatus = await Permission.storage.request(); + // if (storageStatus.isGranted == false) { + // print('存储权限未申请'); + // } else { + // print('存储权限已申请'); + // } + + if (controller.text.isEmpty) { + return; + } + + setState(() { + fileStream = DefaultCacheManager() + .getFileStream(controller.text, withProgress: true); + }); + } + + void _downloadFile() async { + print( + 'ohFlutter: ------------------------------------------------------------'); + if (controller.text.isEmpty) { + return; + } + + setState(() { + fileStream = DefaultCacheManager() + .getFileStream(controller.text, withProgress: true); + }); + } + + @override + Widget build(BuildContext context) { + if (fileStream == null) { + controller.text = staticUrl; + return Scaffold( + appBar: AppBar( + title: const Text('请先下载图片'), + ), + body: ListView( + children: [ + Container( + child: TextField( + controller: controller, + ), + ), + const ListTile( + title: Text('请输入图片的网络地址或重置url, 然后点击浮动动作按钮下载'), + ), + FilledButton( + onPressed: _downloadFile, + child: const Icon(Icons.cloud_download), + ), + FilledButton( + onPressed: () { + setState(() { + controller.text = staticUrl; + }); + }, + child: const Icon(Icons.refresh), + ), + FilledButton( + onPressed: _testDownloadFile, + child: const Icon(Icons.network_check_outlined), + ), + // Image.asset('assets/image-120.png'), + // const Text('这里是显示静态图片的'), + // todo 这里下面的都是测试的内容 + Container( + width: MediaQuery.of(context).size.width * 0.9, + height: 1, + margin: const EdgeInsets.only(top: 20), + decoration: const BoxDecoration(color: Colors.black), + ), + const Text('临时测试权限按钮'), + TextButton( + onPressed: () async { + if (lock == true) { + return; + } + setState(() { + lock = true; + statusCode = ''; + dioGet = ''; + }); + try { + final dio = Dio(); + final Response response = await dio.get( + staticUrl, + options: Options( + responseType: ResponseType.bytes, // 设置响应类型为字节数组 + ), + ); + print('请求的状态码: ${response.statusCode}'); + + print('ohFlutter: 这里是dio获取到的网络信息${response.data}'); + setState(() { + statusCode = response.statusCode.toString(); + dioGet = response.data.toString(); + }); + } catch (e) { + setState(() { + dioGet = e.toString(); + }); + } finally { + setState(() { + lock = false; + }); + } + }, + child: const Text('点击获取http图片信息, dio.get')), + Visibility( + visible: lock, + child: const Text( + '当前正在进行网络请求', + style: TextStyle(color: Colors.red), + )), + Visibility( + visible: !lock, + child: Column( + children: [ + Text('这里显示获取到的状态码: $statusCode'), + + Text('这里显示获取到的网络信息: $dioGet'), + ], + )) + ], + ), + ); + } + return DownloadPage( + fileStream: fileStream!, + downloadFile: _downloadFile, + clearCache: _clearCache, + removeFile: _removeFile, + ); + } + + void _clearCache() { + DefaultCacheManager().emptyCache(); + setState(() { + fileStream = null; + }); + } + + void _removeFile() { + DefaultCacheManager().removeFile(controller.text).then((value) { + if (kDebugMode) { + print('File removed'); + } + }).onError((error, stackTrace) { + if (kDebugMode) { + print(error); + } + }); + setState(() { + fileStream = null; + }); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/plugin_example/progress_indicator.dart b/ohos/test_flutter_cache_manager/lib/plugin_example/progress_indicator.dart new file mode 100644 index 0000000000000000000000000000000000000000..4bea8d16679fa49b35becea1fc5be356b7548b44 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/plugin_example/progress_indicator.dart @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +/// A centered and sized [CircularProgressIndicator] to show download progress +/// in the [DownloadPage]. +class ProgressIndicator extends StatelessWidget { + const ProgressIndicator({this.progress}); + + final DownloadProgress? progress; + + @override + Widget build(BuildContext context) { + return Center( + child: Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + SizedBox( + width: 50, + height: 50, + child: CircularProgressIndicator.adaptive( + value: progress?.progress, + ), + ), + const SizedBox(width: 20), + const Text('下载'), + ], + ), + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/cache_manager_test.dart b/ohos/test_flutter_cache_manager/lib/src/cache_manager_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ce7ff76ca7ad1ff7804f110a3315567b40b38b29 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/cache_manager_test.dart @@ -0,0 +1,474 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:typed_data'; + +import 'package:clock/clock.dart'; +import 'package:file/memory.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/cache_store.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:flutter_cache_manager/src/web/web_helper.dart'; +import 'package:mockito/mockito.dart'; + +import '../common/test_page.dart'; +import 'helpers/config_extensions.dart'; +import 'helpers/mock_cache_store.dart'; +import 'helpers/mock_file_fetcher_response.dart'; +import 'helpers/test_configuration.dart'; +import 'mock.mocks.dart'; + +class CacheManagerTestPage extends TestPage { + CacheManagerTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('Tests for getSingleFile', () { + test('有效的cacheFile不应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var validTill = DateTime.now().add(const Duration(days: 1)); + + var config = createTestConfig(); + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill); + + var cacheManager = TestCacheManager(config); + var result = await cacheManager.getSingleFile(fileUrl); + result; + config.verifyNoDownloadCall(); + }); + + test('过时的cacheFile应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var validTill = DateTime.now().subtract(const Duration(days: 1)); + + var config = createTestConfig(); + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill); + + var cacheManager = TestCacheManager(config); + + var result = await cacheManager.getSingleFile(fileUrl); + result; + await config.waitForDownload(); + config.verifyDownloadCall(); + }); + + test('不存在的cacheFile应调用web', () async { + var fileUrl = 'baseflow.com/test'; + + var config = createTestConfig(); + config.returnsNoCacheObject(fileUrl); + + var cacheManager = TestCacheManager(config); + + var result = await cacheManager.getSingleFile(fileUrl); + result; + config.verifyDownloadCall(); + }); + }); + + group('CacheManager.getSingleFile', () { + test('有效的cacheFile不应调用web', () async { + var config = createTestConfig(); + + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var fileKey = 'test1234'; + var validTill = DateTime.now().add(const Duration(days: 1)); + + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill, key: fileKey); + var cacheManager = TestCacheManager(config); + + var result = await cacheManager.getSingleFile(fileUrl, key: fileKey); + result; + config.verifyNoDownloadCall(); + }); + + test('过时的cacheFile应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var fileKey = 'test1234'; + var validTill = DateTime.now().subtract(const Duration(days: 1)); + + var config = createTestConfig(); + config.returnsCacheObject(fileUrl, fileName, validTill, key: fileKey); + await config.returnsFile(fileName); + + var cacheManager = TestCacheManager(config); + + var result = await cacheManager.getSingleFile(fileUrl, key: fileKey); + await config.waitForDownload(); + result; + config.verifyDownloadCall(); + }); + + // test('Non-existing cacheFile should call to web', () async { + // var fileName = 'test.jpg'; + // var fileUrl = 'baseflow.com/test'; + // var fileKey = 'test1234'; + // var validTill = DateTime.now().subtract(const Duration(days: 1)); + // + // var config = createTestConfig(); + // config.returnsCacheObject(fileUrl, fileName, validTill, key: fileKey); + // + // var cacheManager = TestCacheManager(config); + // + // var result = await cacheManager.getSingleFile(fileUrl, key: fileKey); + // expect(result, isNotNull); + // config.verifyDownloadCall(); + // }); + }); + + group('CacheManager.getFile', () { + test('有效的cacheFile不应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var validTill = DateTime.now().add(const Duration(days: 1)); + + var config = createTestConfig(); + config.returnsCacheObject(fileUrl, fileName, validTill); + await config.returnsFile(fileName); + + var store = MockCacheStore(); + var file = await createTestConfig().fileSystem.createFile(fileName); + var fileInfo = FileInfo(file, FileSource.Cache, validTill, fileUrl); + when(store.getFile(fileUrl)).thenAnswer((_) => Future.value(fileInfo)); + + var cacheManager = TestCacheManager(config, store: store); + + // ignore: deprecated_member_use_from_same_package + var fileStream = cacheManager.getFile(fileUrl); + expect(fileStream, (fileInfo)); + config.verifyNoDownloadCall(); + }); + + test('过时的cacheFile应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var validTill = DateTime.now().subtract(const Duration(days: 1)); + + var store = MockCacheStore(); + var file = await createTestConfig().fileSystem.createFile(fileName); + var cachedInfo = FileInfo(file, FileSource.Cache, validTill, fileUrl); + when(store.getFile(fileUrl)).thenAnswer((_) => Future.value(cachedInfo)); + + var webHelper = MockWebHelper(); + var downloadedInfo = FileInfo(file, FileSource.Online, + DateTime.now().add(const Duration(days: 1)), fileUrl); + when(webHelper.downloadFile(fileUrl, key: anyNamed('key'))) + .thenAnswer((_) => Stream.value(downloadedInfo)); + + var cacheManager = TestCacheManager(createTestConfig(), + store: store, webHelper: webHelper); + + // ignore: deprecated_member_use_from_same_package + var fileStream = cacheManager.getFile(fileUrl); + + }); + + test('不存在的cacheFile应调用web', () async { + var fileName = 'test.jpg'; + var fileUrl = 'baseflow.com/test'; + var validTill = DateTime.now().subtract(const Duration(days: 1)); + + var store = MockCacheStore(); + var file = await createTestConfig().fileSystem.createFile(fileName); + var fileInfo = FileInfo(file, FileSource.Cache, validTill, fileUrl); + + when(store.getFile(fileUrl)).thenAnswer((_) => Future.value(null)); + + var webHelper = MockWebHelper(); + when(webHelper.downloadFile(fileUrl, key: anyNamed('key'))) + .thenAnswer((_) => Stream.value(fileInfo)); + + var cacheManager = TestCacheManager( + createTestConfig(), + store: store, + webHelper: webHelper, + ); + + // ignore: deprecated_member_use_from_same_package + var fileStream = cacheManager.getFile(fileUrl); + + }); + + test('应将错误传递到流', () async { + var fileUrl = 'baseflow.com/test'; + + var store = MockCacheStore(); + when(store.getFile(fileUrl)).thenAnswer((_) => Future.value(null)); + + var webHelper = MockWebHelper(); + var error = HttpExceptionWithStatus(404, 'Invalid statusCode: 404', + uri: Uri.parse(fileUrl)); + when(webHelper.downloadFile(fileUrl, key: anyNamed('key'))) + .thenThrow(error); + + var cacheManager = TestCacheManager( + createTestConfig(), + store: store, + webHelper: webHelper, + ); + + // ignore: deprecated_member_use_from_same_package + var fileStream = cacheManager.getFile(fileUrl); + + }); + }); + + group('CacheManager.putFile', () { + test('检查是否写入了文件并存储了信息', () async { + var fileUrl = 'baseflow.com/test'; + var fileBytes = Uint8List(16); + var extension = 'jpg'; + + var store = MockCacheStore(); + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + var file = await cacheManager.putFile(fileUrl, fileBytes, + fileExtension: extension); + expect(await file.exists(), true); + expect(await file.readAsBytes(), fileBytes); + verify(store.putFile(any)); + }); + + test('检查是否写入文件并存储信息,显式密钥', () async { + var fileUrl = 'baseflow.com/test'; + var fileBytes = Uint8List(16); + var fileKey = 'test1234'; + var extension = 'jpg'; + + var store = MockCacheStore(); + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + var file = await cacheManager.putFile(fileUrl, fileBytes, + key: fileKey, fileExtension: extension); + expect(await file.exists(), true); + expect(await file.readAsBytes(), fileBytes); + final arg = + verify(store.putFile(captureAny)).captured.first as CacheObject; + expect(arg.key, fileKey); + expect(arg.url, fileUrl); + }); + + test('检查是否写入了文件并存储了信息', () async { + var fileUrl = 'baseflow.com/test'; + var extension = 'jpg'; + var memorySystem = + await MemoryFileSystem().systemTempDirectory.createTemp('origin'); + + var existingFile = memorySystem.childFile('testfile.jpg'); + var fileBytes = Uint8List(16); + await existingFile.writeAsBytes(fileBytes); + + var store = MockCacheStore(); + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + var file = await cacheManager.putFileStream( + fileUrl, existingFile.openRead(), + fileExtension: extension); + expect(await file.exists(), true); + expect(await file.readAsBytes(), fileBytes); + verify(store.putFile(any)); + }); + + test('检查是否写入文件并存储信息,显式密钥', () async { + var fileUrl = 'baseflow.com/test'; + var fileKey = 'test1234'; + var extension = 'jpg'; + var memorySystem = + await MemoryFileSystem().systemTempDirectory.createTemp('origin'); + + var existingFile = memorySystem.childFile('testfile.jpg'); + var fileBytes = Uint8List(16); + await existingFile.writeAsBytes(fileBytes); + + var store = MockCacheStore(); + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + var file = await cacheManager.putFileStream( + fileUrl, existingFile.openRead(), + key: fileKey, fileExtension: extension); + expect(await file.exists(), true); + expect(await file.readAsBytes(), fileBytes); + final arg = + verify(store.putFile(captureAny)).captured.first as CacheObject; + expect(arg.key, fileKey); + expect(arg.url, fileUrl); + }); + }); + + group('CacheManager.removeFile', () { + test('从缓存中删除现有文件', () async { + var fileUrl = 'baseflow.com/test'; + + var store = MockCacheStore(); + when(store.retrieveCacheData(fileUrl)) + .thenAnswer((_) => Future.value(CacheObject( + fileUrl, + relativePath: 'test.png', + validTill: clock.now(), + id: 123, + ))); + + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + await cacheManager.removeFile(fileUrl); + verify(store.removeCachedFile(any)); + }); + + test("不删除不在缓存中的文件", () async { + var fileUrl = 'baseflow.com/test'; + + var store = MockCacheStore(); + when(store.retrieveCacheData(fileUrl)) + .thenAnswer((_) => Future.value(null)); + + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + await cacheManager.removeFile(fileUrl); + verifyNever(store.removeCachedFile(any)); + }); + + test("如果缓存的对象没有id,则不要崩溃", () async { + var fileUrl = 'baseflow.com/test'; + + var store = MockCacheStore(); + when(store.retrieveCacheData(fileUrl)) + .thenAnswer((_) => Future.value(CacheObject( + fileUrl, + relativePath: 'test.png', + validTill: clock.now(), + id: null, + ))); + + var cacheManager = TestCacheManager(createTestConfig(), store: store); + + await cacheManager.removeFile(fileUrl); + // Don't call remove cache if the id is null + verifyNever(store.removeCachedFile(any)); + }); + }); + + test('CacheManager.downloadFile', () async { + var fileUrl = 'baseflow.com/test'; + var fileInfo = FileInfo(MemoryFileSystem.test().file('f'), FileSource.Cache, + DateTime.now(), fileUrl); + var store = MockCacheStore(); + var webHelper = MockWebHelper(); + when(webHelper.downloadFile(fileUrl, key: anyNamed('key'))) + .thenAnswer((_) => Stream.value(fileInfo)); + var cacheManager = TestCacheManager( + createTestConfig(), + webHelper: webHelper, + store: store, + ); + expect(await cacheManager.downloadFile(fileUrl), fileInfo); + }); + + test('CacheManager.getFileFromMemory', () async { + var fileUrl = 'baseflow.com/test'; + var fileInfo = FileInfo(MemoryFileSystem.test().file('f'), FileSource.Cache, + DateTime.now(), fileUrl); + + var store = MockCacheStore(); + when(store.getFileFromMemory(fileUrl)) + .thenAnswer((realInvocation) async => fileInfo); + var webHelper = MockWebHelper(); + var cacheManager = TestCacheManager(createTestConfig(), + store: store, webHelper: webHelper); + var result = await cacheManager.getFileFromMemory(fileUrl); + expect(result, fileInfo); + }); + + test('CacheManager.emptyCache', () async { + var store = MockCacheStore(); + var cacheManager = TestCacheManager(createTestConfig(), store: store); + await cacheManager.emptyCache(); + verify(store.emptyCache()); + }); + + group('CacheManager.getFileStream', () { + test('王往stream里面输入进度', () async { + var fileUrl = 'baseflow.com/test'; + + var config = createTestConfig(); + var fileService = config.fileService; + var downloadStreamController = StreamController>(); + when(fileService.get(fileUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + downloadStreamController.stream, + 6, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + var cacheManager = TestCacheManager(config); + + var fileStream = cacheManager.getFileStream(fileUrl, withProgress: true); + downloadStreamController.add([0]); + downloadStreamController.add([1]); + downloadStreamController.add([2, 3]); + downloadStreamController.add([4]); + downloadStreamController.add([5]); + await downloadStreamController.close(); + + config = createTestConfig(); + + fileUrl = 'baseflow.com/test'; + + var store = MockCacheStore(); + + when(store.getFile(fileUrl)).thenAnswer((_) => Future.value(null)); + + downloadStreamController = StreamController>(); + when(config.fileService.get(fileUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + downloadStreamController.stream, + 6, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + cacheManager = TestCacheManager(config); + + fileStream = cacheManager.getFileStream(fileUrl); + downloadStreamController.add([0]); + downloadStreamController.add([1]); + downloadStreamController.add([2, 3]); + downloadStreamController.add([4]); + downloadStreamController.add([5]); + await downloadStreamController.close(); + }); + }); +} +} +class TestCacheManager extends CacheManager with ImageCacheManager { + TestCacheManager( + Config? config, { + CacheStore? store, + WebHelper? webHelper, + }) : super.custom(config ?? createTestConfig(), + cacheStore: store, webHelper: webHelper); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/cache_object_test.dart b/ohos/test_flutter_cache_manager/lib/src/cache_object_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c32c3e16a9ff00426c95a7acf87cf2f5b0b80483 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/cache_object_test.dart @@ -0,0 +1,238 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:clock/clock.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; + +import '../common/test_page.dart'; + +class CacheObjectTestPage extends TestPage { + CacheObjectTestPage(String title, {Key? key}) + : super(title: title, key: key) { + const columnId = '_id'; + const columnUrl = 'url'; + const columnKey = 'key'; + const columnPath = 'relativePath'; + const columnETag = 'eTag'; + const columnValidTill = 'validTill'; + const columnTouched = 'touched'; + + const validMillis = 1585301160000; + final validDate = DateTime.utc(2020, 03, 27, 09, 26).toLocal(); + final now = DateTime(2020, 03, 28, 09, 26); + + const testId = 1; + const relativePath = 'test.png'; + const testUrl = 'www.test.com/image'; + const testKey = 'test123'; + const eTag = 'test1'; + + test('CacheObject,.key CacheObject.url', () { + var object = CacheObject( + 'baseflow.com/test.png', + relativePath: 'test.png', + validTill: validDate, + eTag: 'test1', + id: 3, + ); + expect(object.url, 'baseflow.com/test.png'); + expect(object.key, object.url); + + object = CacheObject( + 'baseflow.com/test.png', + key: 'test key 1234', + relativePath: 'test.png', + validTill: validDate, + eTag: 'test1', + id: 3, + ); + expect(object.url, 'baseflow.com/test.png'); + expect(object.key, 'test key 1234'); + }); + + group('Test CacheObject mapping', () { + test('使用map创建CacheObject()', () { + var map = { + columnId: 3, + columnUrl: 'baseflow.com/test.png', + columnPath: 'test.png', + columnETag: 'test1', + columnValidTill: validMillis, + columnTouched: now.millisecondsSinceEpoch + }; + var object = CacheObject.fromMap(map); + expect(object.id, 3); + expect(object.url, 'baseflow.com/test.png'); + expect(object.key, object.url); + expect(object.relativePath, 'test.png'); + expect(object.eTag, 'test1'); + expect(object.validTill, validDate); + + map = { + columnId: 3, + columnUrl: 'baseflow.com/test.png', + columnKey: 'testId1234', + columnPath: 'test.png', + columnETag: 'test1', + columnValidTill: validMillis, + columnTouched: now.millisecondsSinceEpoch + }; + object = CacheObject.fromMap(map); + expect(object.id, 3); + expect(object.url, 'baseflow.com/test.png'); + expect(object.key, 'testId1234'); + expect(object.relativePath, 'test.png'); + expect(object.eTag, 'test1'); + expect(object.validTill, validDate); + }); + + test('CacheObject.toMap', () async { + await withClock(Clock.fixed(now), () async { + var object = CacheObject( + 'baseflow.com/test.png', + key: 'testKey1234', + relativePath: 'test.png', + validTill: validDate, + eTag: 'test1', + id: 3, + ); + + var map = object.toMap(); + expect(map[columnId], 3); + expect(map[columnUrl], 'baseflow.com/test.png'); + expect(map[columnKey], 'testKey1234'); + expect(map[columnPath], 'test.png'); + expect(map[columnETag], 'test1'); + expect(map[columnValidTill], validMillis); + expect(map[columnTouched], now.millisecondsSinceEpoch); + }); + }); + }); + + group('CacheObject.copyWith', () { + test('copy with id', () { + var cacheObject = CacheObject( + testUrl, + id: null, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + var newObject = cacheObject.copyWith(id: testId); + expect(newObject.id, testId); + expect(newObject.url, testUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, relativePath); + expect(newObject.validTill, now); + expect(newObject.eTag, eTag); + expect(newObject.length, 200); + + cacheObject = CacheObject( + testUrl, + id: testId, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + const newUrl = 'www.someotherurl.com'; + newObject = cacheObject.copyWith(url: newUrl); + expect(newObject.id, testId); + expect(newObject.url, newUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, relativePath); + expect(newObject.validTill, now); + expect(newObject.eTag, eTag); + expect(newObject.length, 200); + + cacheObject = CacheObject( + testUrl, + id: testId, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + newObject = cacheObject.copyWith(relativePath: 'newPath.jpg'); + expect(newObject.id, testId); + expect(newObject.url, testUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, 'newPath.jpg'); + expect(newObject.validTill, now); + expect(newObject.eTag, eTag); + expect(newObject.length, 200); + + cacheObject = CacheObject( + testUrl, + id: testId, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + newObject = cacheObject.copyWith(validTill: validDate); + expect(newObject.id, testId); + expect(newObject.url, testUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, relativePath); + expect(newObject.validTill, validDate); + expect(newObject.eTag, eTag); + expect(newObject.length, 200); + + cacheObject = CacheObject( + testUrl, + id: testId, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + newObject = cacheObject.copyWith(eTag: 'fileChangedRecently'); + expect(newObject.id, testId); + expect(newObject.url, testUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, relativePath); + expect(newObject.validTill, now); + expect(newObject.eTag, 'fileChangedRecently'); + expect(newObject.length, 200); + + cacheObject = CacheObject( + testUrl, + id: testId, + key: testKey, + relativePath: relativePath, + validTill: now, + eTag: eTag, + length: 200, + ); + newObject = cacheObject.copyWith(length: 300); + expect(newObject.id, testId); + expect(newObject.url, testUrl); + expect(newObject.key, testKey); + expect(newObject.relativePath, relativePath); + expect(newObject.validTill, now); + expect(newObject.eTag, eTag); + expect(newObject.length, 300); + }); + }); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/cache_store_test.dart b/ohos/test_flutter_cache_manager/lib/src/cache_store_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..47ef75c053f107508a9314279d8d01b615e720e7 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/cache_store_test.dart @@ -0,0 +1,370 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:clock/clock.dart'; +import 'package:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/src/cache_store.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:matcher/src/interfaces.dart'; +import 'package:mockito/mockito.dart'; + +import '../common/test_page.dart'; +import 'helpers/config_extensions.dart'; +import 'helpers/mock_cache_info_repository.dart'; +import 'helpers/test_configuration.dart'; + +class CacheStoreTestPage extends TestPage { + CacheStoreTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('Retrieving files from store', () { + test('当文件未缓存时,存储应返回null', () async { + var repo = MockCacheInfoRepository(); + when(repo.get(any)).thenAnswer((_) => Future.value(null)); + var store = CacheStore(createTestConfig()); + + expect(await store.getFile('This is a test'), null); + }); + + test('缓存文件时,存储应返回FileInfo', () async { + var fileName = 'testimage.png'; + var fileUrl = 'baseflow.com/test.png'; + + var config = createTestConfig(); + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, DateTime.now()); + + var tempDir = createDir(); + await (await tempDir).childFile('testimage.png').create(); + + var store = CacheStore(config); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + }); + + test('不再缓存文件时,存储应返回null', () async { + var repo = MockCacheInfoRepository(); + + when(repo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + validTill: clock.now().add(const Duration(days: 7)), + ))); + var store = CacheStore(createTestConfig()); + + expect(await store.getFile('baseflow.com/test.png'), null); + }); + + test('文件未缓存时,存储不应返回CacheInfo', () async { + var repo = MockCacheInfoRepository(); + when(repo.get(any)).thenAnswer((_) => Future.value(null)); + var store = CacheStore(createTestConfig()); + + expect(await store.retrieveCacheData('This is a test'), null); + }); + + test('缓存文件时,存储应返回CacheInfo', () async { + var fileName = 'testimage.png'; + var fileUrl = 'baseflow.com/test.png'; + + var config = createTestConfig(); + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, DateTime.now(), id: 1); + + var store = CacheStore(config); + final cacheObject = await store.retrieveCacheData(fileUrl); + expect(cacheObject!=null, true); + expect(cacheObject!.id!=null, true); + }); + + test('当请求两次时,存储应从内存返回CacheInfo', + () async { + var fileName = 'testimage.png'; + var fileUrl = 'baseflow.com/test.png'; + var validTill = DateTime.now(); + var config = createTestConfig(); + + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill, id: 1); + var store = CacheStore(config); + + var result = await store.retrieveCacheData(fileUrl); + expect(result!=null, true); + expect(result!.id!=null, true); + + var otherResult = await store.retrieveCacheData(fileUrl); + expect(otherResult!.id!=null, true); + + verify(config.mockRepo.get(any)); + }); + + test( + '只有在之前检索到文件时,存储才应从memcache返回File', + () async { + var fileName = 'testimage.png'; + var fileUrl = 'baseflow.com/test.png'; + var validTill = DateTime.now(); + var config = createTestConfig(); + + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill); + + var store = CacheStore(config); + + expect(await store.getFileFromMemory(fileUrl), null); + await store.getFile(fileUrl); + expect(await store.getFileFromMemory(fileUrl)!=null, true); + }); + }); + + group('Storing files in store', () { + test('存储应将fileinfo存储在repo中', () async { + var config = createTestConfig(); + var store = CacheStore(config); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + validTill: clock.now().add(const Duration(days: 7)), + ); + await store.putFile(cacheObject); + + verify(config.repo.updateOrInsert(cacheObject)); + }); + + test( + 'Store应将fileinfo存储在repo中,之后id应可用', + () async { + var config = createTestConfig(); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + validTill: clock.now().add(const Duration(days: 7)), + ); + + await config.returnsFile(cacheObject.relativePath); + when(config.mockRepo.updateOrInsert(cacheObject)).thenAnswer( + (realInvocation) async => cacheObject.copyWith(id: 1), + ); + + var store = CacheStore(config); + await store.putFile(cacheObject); + + verify(config.repo.updateOrInsert(cacheObject)); + + final result = await store.retrieveCacheData(cacheObject.key); + expect(result!.id!=null, true); + }); + }); + + group('Removing files in store', () { + test('存储应在删除时从repo中删除fileinfo', () async { + var fileName = 'testimage.png'; + var fileUrl = 'baseflow.com/test.png'; + var validTill = DateTime.now(); + var config = createTestConfig(); + + await config.returnsFile(fileName); + config.returnsCacheObject(fileUrl, fileName, validTill); + + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + + var cacheObject = CacheObject( + fileUrl, + relativePath: fileName, + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + await store.removeCachedFile(cacheObject); + + }); + + test('存储应删除超过容量的文件', () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + await config.returnsFile('testimage.png'); + + when(config.mockRepo.getObjectsOverCapacity(any)) + .thenAnswer((_) => Future.value([cacheObject])); + when(config.mockRepo.getOldObjects(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(cacheObject)); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + + await untilCalled(config.mockRepo.deleteAll(any)); + + verify(config.mockRepo.getObjectsOverCapacity(any)); + }); + + test('存储应删除过旧的文件', () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + await config.returnsFile('testimage.png'); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + + when(config.mockRepo.getObjectsOverCapacity(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.getOldObjects(any)) + .thenAnswer((_) => Future.value([cacheObject])); + when(config.mockRepo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(cacheObject)); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + + await untilCalled(config.mockRepo.deleteAll(any)); + + verify(config.mockRepo.getOldObjects(any)); + }); + + test('存储应删除旧的和容量过大的文件', () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + await config.returnsFile('testimage.png'); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + + when(config.mockRepo.getObjectsOverCapacity(any)) + .thenAnswer((_) => Future.value([cacheObject])); + when(config.mockRepo.getOldObjects(any)) + .thenAnswer((_) => Future.value([cacheObject])); + when(config.mockRepo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(cacheObject)); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + + await untilCalled(config.mockRepo.deleteAll(any)); + await Future.delayed(const Duration(milliseconds: 5)); + + verify(config.mockRepo.getObjectsOverCapacity(any)); + verify(config.mockRepo.getOldObjects(any)); + }); + + test('删除文件时,存储应重新检查缓存信息', () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + var file = await config.returnsFile('testimage.png'); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + + when(config.mockRepo.getObjectsOverCapacity(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.getOldObjects(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(cacheObject)); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + await file.delete(); + expect(await store.getFile('baseflow.com/test.png')==null, true); + }); + + test('存储不应删除不旧或容量过大的文件', + () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + await config.returnsFile('testimage.png'); + + var cacheObject = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + + when(config.mockRepo.getObjectsOverCapacity(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.getOldObjects(any)) + .thenAnswer((_) => Future.value([])); + when(config.mockRepo.get('baseflow.com/test.png')) + .thenAnswer((_) => Future.value(cacheObject)); + + expect(await store.getFile('baseflow.com/test.png')!=null, true); + + await untilCalled(config.mockRepo.deleteAll(any)); + + verify(config.mockRepo.getOldObjects(any)); + }); + + test('清空缓存时,存储应删除所有文件', () async { + var config = createTestConfig(); + var store = CacheStore(config); + store.cleanupRunMinInterval = const Duration(milliseconds: 1); + await config.returnsFile('testimage.png'); + + var co1 = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage1.png', + id: 1, + validTill: clock.now().add(const Duration(days: 7)), + ); + var co2 = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage2.png', + id: 2, + validTill: clock.now().add(const Duration(days: 7)), + ); + var co3 = CacheObject( + 'baseflow.com/test.png', + relativePath: 'testimage3.png', + id: 3, + validTill: clock.now().add(const Duration(days: 7)), + ); + + when(config.mockRepo.getAllObjects()) + .thenAnswer((_) => Future.value([co1, co2, co3])); + + await store.emptyCache(); + + }); + }); +} +} +Future createDir() async { + final fileSystem = MemoryFileSystem(); + return fileSystem.systemTempDirectory.createTemp('test'); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/config_extensions.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/config_extensions.dart new file mode 100644 index 0000000000000000000000000000000000000000..542a8584890b54d509e891c6887f5aee750270e3 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/config_extensions.dart @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:file/file.dart'; +import 'package:flutter_cache_manager/src/config/config.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:mockito/mockito.dart'; + +import 'mock_cache_info_repository.dart'; +import 'mock_file_service.dart'; + +extension ConfigExtensions on Config { + MockCacheInfoRepository get mockRepo => repo as MockCacheInfoRepository; + + MockFileService get mockFileService => fileService as MockFileService; + + Future returnsFile(String fileName, {List? data}) async { + var file = await fileSystem.createFile(fileName); + await (file.openWrite()..add(data ?? [1, 3])).close(); + return file; + } + + void returnsCacheObject( + String fileUrl, + String fileName, + DateTime validTill, { + String? key, + int? id, + }) { + when(repo.get(key ?? fileUrl)) + .thenAnswer((realInvocation) async => CacheObject( + fileUrl, + relativePath: fileName, + validTill: validTill, + key: key ?? fileUrl, + id: id, + )); + } + + void returnsNoCacheObject(String fileUrl) { + when(repo.get(fileUrl)).thenAnswer((realInvocation) async => null); + } + + void verifyNoDownloadCall() { + verifyNoMoreInteractions(fileService); + verifyNever( + mockFileService.get(any, headers: anyNamed('headers')), + ); + verifyNever(mockFileService.get(any)); + } + + Future waitForDownload() async { + await untilCalled(mockFileService.get(any, headers: anyNamed('headers'))); + } + + void verifyDownloadCall([int count = 1]) { + verify( + mockFileService.get(any, headers: anyNamed('headers')), + ); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/json_repo_helpers.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/json_repo_helpers.dart new file mode 100644 index 0000000000000000000000000000000000000000..4eec77c1c8200ccf5bcb97e2731244ce697f4a1d --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/json_repo_helpers.dart @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:convert'; + +import 'package:clock/clock.dart'; +import 'package:file/file.dart'; +import 'package:file/memory.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; + +const String databaseName = 'test'; +const String path = + '/data/user/0/com.example.test_flutter_cache_manager/databases/$databaseName.json'; +final directory = MemoryFileSystem().directory('database'); +const String testurl = 'www.baseflow.com/test.png'; +const String testurl2 = 'www.baseflow.com/test2.png'; +const String testurl3 = 'www.baseflow.com/test3.png'; +const String testurl4 = 'www.baseflow.com/test4.png'; + +class JsonRepoHelpers { + static Future createRepository( + {bool open = true}) async { + var directory = await _createDirectory(); + var file = await _createFile(directory); + var repository = JsonCacheInfoRepository.withFile(file); + if (open) await repository.open(); + return repository; + } + + static Future _createDirectory() async { + var testDir = + await MemoryFileSystem().systemTempDirectory.createTemp('testFolder'); + await testDir.create(recursive: true); + return testDir; + } + + static Future _createFile(Directory dir) { + var file = dir.childFile('$databaseName.json'); + var json = jsonEncode(_createCacheObjects()); + return file.writeAsString(json); + } + + static List> _createCacheObjects() { + return startCacheObjects + .map((e) => e.toMap(setTouchedToNow: false)) + .toList(); + } + + static final defaultValidTill = clock.now().add(const Duration(days: 7)); + static const defaultRelativePath = 'test.png'; + static final List startCacheObjects = [ + // Old object + CacheObject( + testurl, + key: testurl, + id: 1, + touched: clock.now().subtract(const Duration(days: 8)), + validTill: defaultValidTill, + relativePath: defaultRelativePath, + ), + // New object + CacheObject( + testurl2, + key: testurl2, + id: 2, + touched: clock.now(), + validTill: defaultValidTill, + relativePath: defaultRelativePath, + ), + // A less new object + CacheObject( + testurl3, + key: testurl3, + id: 3, + touched: clock.now().subtract(const Duration(minutes: 1)), + validTill: defaultValidTill, + relativePath: defaultRelativePath, + ), + ]; + static final CacheObject extraCacheObject = CacheObject( + testurl4, + key: testurl4, + validTill: defaultValidTill, + relativePath: defaultRelativePath, + ); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_info_repository.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_info_repository.dart new file mode 100644 index 0000000000000000000000000000000000000000..724b5225dddce98a1e6e80541bed725df5524ab1 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_info_repository.dart @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:mockito/mockito.dart'; + +import '../mock.mocks.dart'; + +class MockCacheInfoRepository extends MockCacheInfoRepositoryBase { + MockCacheInfoRepository._(); + + factory MockCacheInfoRepository() { + var provider = MockCacheInfoRepository._(); + when(provider.delete(any)).thenAnswer((_) => Future.value(0)); + when(provider.deleteAll(any)).thenAnswer((_) => Future.value(0)); + when(provider.get(any)).thenAnswer((_) => Future.value(null)); + when(provider.insert(any, setTouchedToNow: anyNamed('setTouchedToNow'))) + .thenAnswer((realInvocation) { + return Future.value( + realInvocation.positionalArguments.first as CacheObject); + }); + when(provider.open()).thenAnswer((_) => Future.value(true)); + when(provider.update(any, setTouchedToNow: anyNamed('setTouchedToNow'))) + .thenAnswer((realInvocation) => Future.value(0)); + when(provider.updateOrInsert(any)).thenAnswer((realInvocation) async => + Future.value(realInvocation.positionalArguments.first)); + when(provider.getObjectsOverCapacity(any)) + .thenAnswer((realInvocation) async => Future.value([])); + when(provider.getOldObjects(any)) + .thenAnswer((realInvocation) async => Future.value([])); + return provider; + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_store.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_store.dart new file mode 100644 index 0000000000000000000000000000000000000000..edd7753ecab0da8853f6bdd69139657a719adbc2 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_cache_store.dart @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:mockito/mockito.dart'; + +import '../mock.mocks.dart'; + +class MockCacheStore extends MockCacheStoreBase { + MockCacheStore._(); + + factory MockCacheStore() { + final store = MockCacheStore._(); + when(store.retrieveCacheData(any, + ignoreMemCache: anyNamed('ignoreMemCache'))) + .thenAnswer((_) => Future.value(null)); + return store; + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_fetcher_response.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_fetcher_response.dart new file mode 100644 index 0000000000000000000000000000000000000000..ada86d93a49dff05a7d23b8ad67dd477ed33de09 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_fetcher_response.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter_cache_manager/src/web/file_service.dart'; + +class MockFileFetcherResponse implements FileServiceResponse { + final Stream> _content; + final int? _contentLength; + final String? _eTag; + final String _fileExtension; + final int _statusCode; + final DateTime _validTill; + + factory MockFileFetcherResponse.basic() { + return MockFileFetcherResponse(Stream.value([0, 1, 2, 3, 4, 5]), 6, + 'testv1', '.jpg', 200, DateTime.now()); + } + + MockFileFetcherResponse(this._content, this._contentLength, this._eTag, + this._fileExtension, this._statusCode, this._validTill); + + @override + Stream> get content => _content; + + @override + String? get eTag => _eTag; + + @override + String get fileExtension => _fileExtension; + + @override + int get statusCode => _statusCode; + + @override + DateTime get validTill => _validTill; + + @override + int? get contentLength => _contentLength; +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_service.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_service.dart new file mode 100644 index 0000000000000000000000000000000000000000..9b1a1e897d048a757d7bf0951c2bf3bf0ac1a870 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/mock_file_service.dart @@ -0,0 +1,65 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/web/file_service.dart'; +import 'package:mockito/mockito.dart'; + +import '../image_cache_manager_test.dart'; +import '../mock.mocks.dart'; + +class MockFileService extends MockFileServiceBase { + MockFileService._(); + + factory MockFileService({bool includeStandardResponse = true}) { + var fileService = MockFileService._(); + if (includeStandardResponse) { + when(fileService.concurrentFetches).thenReturn(2); + when(fileService.get(any, headers: anyNamed('headers'))) + .thenAnswer((realInvocation) async { + return TestResponse(); + }); + } + return fileService; + } +} + +class TestResponse extends FileServiceResponse { + @override + Stream> get content async* { + var bytes = await getExampleImage(); + var length = bytes.length; + var firstPart = (length / 2).floor(); + yield bytes.sublist(0, firstPart); + yield bytes.sublist(firstPart); + } + + @override + int get contentLength => 0; + + @override + String get eTag => 'test'; + + @override + String get fileExtension => '.jpg'; + + @override + int get statusCode => 200; + + @override + DateTime get validTill => DateTime.now(); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/helpers/test_configuration.dart b/ohos/test_flutter_cache_manager/lib/src/helpers/test_configuration.dart new file mode 100644 index 0000000000000000000000000000000000000000..57fac1eb53dde9921df35bb9df54f51aeebcd74c --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/helpers/test_configuration.dart @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:file/file.dart' show File; +import 'package:file/memory.dart'; +import 'package:flutter_cache_manager/src/config/config.dart'; +import 'package:flutter_cache_manager/src/storage/file_system/file_system.dart'; + +import 'mock_cache_info_repository.dart'; +import 'mock_file_service.dart'; + +Config createTestConfig() { + return Config( + 'test', + fileSystem: TestFileSystem(), + repo: MockCacheInfoRepository(), + fileService: MockFileService(), + ); +} + +class TestFileSystem extends FileSystem { + final directoryFuture = + MemoryFileSystem().systemTempDirectory.createTemp('test'); + + @override + Future createFile(String name) async { + var dir = await directoryFuture; + await dir.create(recursive: true); + return dir.childFile(name); + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/http_file_fetcher_test.dart b/ohos/test_flutter_cache_manager/lib/src/http_file_fetcher_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c62ba229074c75034e0b1179d22b15c6ae03f5c7 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/http_file_fetcher_test.dart @@ -0,0 +1,123 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:typed_data'; + +import 'package:clock/clock.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/compat/file_service_compat.dart'; +import 'package:http/http.dart'; +import 'package:http/testing.dart'; + +import '../common/test_page.dart'; + +class HttpFileServiceTestPage extends TestPage { + HttpFileServiceTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('Check header values', () { + test('应正常解析有效的标头', () async { + var eTag = 'test'; + var fileExtension = 'jpg'; + var contentType = 'image/jpeg'; + var contentLength = 16; + var maxAge = const Duration(hours: 2); + + var client = MockClient((request) async { + return Response.bytes(Uint8List(contentLength), 200, headers: { + 'etag': 'test', + 'content-type': contentType, + 'cache-control': 'max-age=${maxAge.inSeconds}' + }); + }); + + await withClock(Clock.fixed(DateTime.now()), () async { + var httpFileFetcher = HttpFileService(httpClient: client); + final now = clock.now(); + final response = await httpFileFetcher.get('test.com/image'); + + expect(response.contentLength, contentLength); + expect(response.eTag, eTag); + expect(response.fileExtension, '.$fileExtension'); + expect(response.validTill, now.add(maxAge)); + expect(response.statusCode, 200); + }); + }); + + test('奇怪的内容类型仍应解析', () async { + var fileExtension = 'cov'; + var contentType = 'unknown/$fileExtension'; + + var client = MockClient((request) async { + return Response.bytes(Uint8List(16), 200, + headers: {'content-type': contentType}); + }); + + var httpFileFetcher = HttpFileService(httpClient: client); + final response = await httpFileFetcher.get('test.com/image'); + + expect(response.fileExtension, '.$fileExtension'); + }); + + test('应忽略内容类型参数', () async { + var fileExtension = 'mp3'; + var contentType = 'audio/mpeg;chartset=UTF-8'; + + var client = MockClient((request) async { + return Response.bytes(Uint8List(16), 200, + headers: {'content-type': contentType}); + }); + + var httpFileFetcher = HttpFileService(httpClient: client); + final response = await httpFileFetcher.get('test.com/document'); + + expect(response.fileExtension, '.$fileExtension'); + }); + + test('FileServiceCompat.get()', () async { + var eTag = 'test'; + var fileExtension = 'jpg'; + var contentType = 'image/jpeg'; + var contentLength = 16; + var maxAge = const Duration(hours: 2); + + var client = MockClient((request) async { + return Response.bytes(Uint8List(contentLength), 200, headers: { + 'etag': 'test', + 'content-type': contentType, + 'cache-control': 'max-age=${maxAge.inSeconds}' + }); + }); + + Future defaultHttpGetter(String url, + {Map? headers}) async { + var httpResponse = await client.get(Uri.parse(url), headers: headers); + return HttpFileFetcherResponse(httpResponse); + } + + await withClock(Clock.fixed(DateTime.now()), () async { + var httpFileFetcher = FileServiceCompat(defaultHttpGetter); + final now = clock.now(); + final response = await httpFileFetcher.get('http://test.com/image'); + + expect(response.contentLength, contentLength); + expect(response.eTag, eTag); + expect(response.fileExtension, '.$fileExtension'); + expect(response.validTill, now.add(maxAge)); + expect(response.statusCode, 200); + }); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/lib/src/image_cache_manager_test.dart b/ohos/test_flutter_cache_manager/lib/src/image_cache_manager_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e9b78329134f73e04f64c99d575cbb54d66283d2 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/image_cache_manager_test.dart @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:ui'; + +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; + +import '../common/test_page.dart'; +import 'cache_manager_test.dart'; +import 'helpers/config_extensions.dart'; +import 'helpers/test_configuration.dart'; + +const fileName = 'test.jpg'; +const fileUrl = 'baseflow.com/test'; +final validTill = DateTime.now().add(const Duration(days: 1)); + +class ImageCacheManagerTestPage extends TestPage { + ImageCacheManagerTestPage(String title, {Key? key}) : super(title: title, key: key) { + PaintingBinding.instance.imageCache.clear(); + PaintingBinding.instance.imageCache.clearLiveImages(); + + + group('Test image resizing', () { + test('测试原始图像大小', () async { + final bytes = await getExampleImage(); + await verifySize(bytes, 120, 120); + }); + + test('当没有给定高度或宽度时,不应修改文件', + () async { + var cacheManager = await setupCacheManager(); + var result = await cacheManager.getImageFile(fileUrl).last as FileInfo; + var image = await result.file.readAsBytes(); + await verifySize(image, 120, 120); + }); + + test('给定高度时不应修改文件', () async { + var cacheManager = await setupCacheManager(); + var result = await cacheManager + .getImageFile( + fileUrl, + maxHeight: 100, + ) + .last as FileInfo; + var image = await result.file.readAsBytes(); + await verifySize(image, 100, 100); + }); + + test('给定宽度时不应修改文件', () async { + var cacheManager = await setupCacheManager(); + var result = await cacheManager + .getImageFile( + fileUrl, + maxWidth: 100, + ) + .last as FileInfo; + var image = await result.file.readAsBytes(); + await verifySize(image, 100, 100); + }); + + test('当给定高度和宽度时,文件应保持纵横比', + () async { + var cacheManager = await setupCacheManager(); + var result = await cacheManager + .getImageFile(fileUrl, maxWidth: 100, maxHeight: 80) + .last as FileInfo; + var image = await result.file.readAsBytes(); + await verifySize(image, 80, 80); + }); + }); + group('Test resized image caching', () { + test('应从缓存中提取调整大小的图像', () async { + var config = await setupConfig(cacheKey: 'resized_w100_h80_$fileUrl'); + var cacheManager = TestCacheManager(config); + var result = await cacheManager + .getImageFile(fileUrl, maxWidth: 100, maxHeight: 80) + .last as FileInfo; + + + config.verifyNoDownloadCall(); + }); + + test('应从缓存中提取未大小的图像', () async { + var config = await setupConfig(); + config.returnsCacheObject( + fileUrl, + fileName, + validTill, + ); + var cacheManager = TestCacheManager(config); + var result = await cacheManager + .getImageFile(fileUrl, maxWidth: 100, maxHeight: 80) + .last as FileInfo; + + + config.verifyNoDownloadCall(); + }); + + test('不应从缓存中提取大小错误的图像', () async { + var config = await setupConfig(cacheKey: 'resized_w100_h150_$fileUrl'); + var cacheManager = TestCacheManager(config); + var result = await cacheManager + .getImageFile(fileUrl, maxWidth: 100, maxHeight: 80) + .last as FileInfo; + + + config.verifyDownloadCall(); + }); + + test('下载应显示进度', () async { + var config = await setupConfig(cacheKey: 'resized_w100_h150_$fileUrl'); + var cacheManager = TestCacheManager(config); + var results = await cacheManager + .getImageFile( + fileUrl, + maxWidth: 100, + maxHeight: 80, + withProgress: true, + ) + .toList(); + var progress = results.whereType().toList(); + print(progress.reversed); + config.verifyDownloadCall(); + }); + }); +} +} +Future setupCacheManager() async { + return TestCacheManager(await setupConfig()); +} + +Future setupConfig({String? cacheKey}) async { + var validTill = DateTime.now().add(const Duration(days: 1)); + var config = createTestConfig(); + await config.returnsFile(fileName, data: await getExampleImage()); + config.returnsCacheObject(fileUrl, fileName, validTill, key: cacheKey); + return config; +} + +Future verifySize( + Uint8List image, + int expectedWidth, + int expectedHeight, +) async { + var codec = await instantiateImageCodec(image); + var frame = await codec.getNextFrame(); + var height = frame.image.height; + var width = frame.image.width; + expect(width, expectedWidth); + expect(height, expectedHeight); +} + +Future getExampleImage() async { + final byteData = await rootBundle.load('assets/image-120.png'); + return byteData.buffer.asUint8List(); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/images/image-120.png b/ohos/test_flutter_cache_manager/lib/src/images/image-120.png new file mode 100644 index 0000000000000000000000000000000000000000..a02e94a16e1ef5f9db866407d36541c1aa0d0f47 Binary files /dev/null and b/ohos/test_flutter_cache_manager/lib/src/images/image-120.png differ diff --git a/ohos/test_flutter_cache_manager/lib/src/mock.dart b/ohos/test_flutter_cache_manager/lib/src/mock.dart new file mode 100644 index 0000000000000000000000000000000000000000..51df571a76d1280f7687c2678abf54eaee01b604 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/mock.dart @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/cache_store.dart'; +import 'package:flutter_cache_manager/src/web/web_helper.dart'; +import 'package:mockito/annotations.dart'; + +@GenerateMocks( + [], + customMocks: [ + MockSpec(as: #MockCacheInfoRepositoryBase), + MockSpec(as: #MockCacheStoreBase), + MockSpec(as: #MockFileServiceBase), + MockSpec(), + ], +) +// ignore: unused_element +void _f() {} diff --git a/ohos/test_flutter_cache_manager/lib/src/mock.mocks.dart b/ohos/test_flutter_cache_manager/lib/src/mock.mocks.dart new file mode 100644 index 0000000000000000000000000000000000000000..bdb616fcee35d836f98a59c1e24a2f6fc9e3f76a --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/mock.mocks.dart @@ -0,0 +1,478 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Mocks generated by Mockito 5.4.2 from annotations +// in flutter_cache_manager/test/mock.dart. +// Do not manually edit this file. + +// ignore_for_file: no_leading_underscores_for_library_prefixes +import 'dart:async' as _i5; + +import 'package:flutter_cache_manager/flutter_cache_manager.dart' as _i4; +import 'package:flutter_cache_manager/src/cache_store.dart' as _i6; +import 'package:flutter_cache_manager/src/storage/cache_object.dart' as _i2; +import 'package:flutter_cache_manager/src/storage/file_system/file_system.dart' + as _i3; +import 'package:flutter_cache_manager/src/web/web_helper.dart' as _i7; +import 'package:mockito/mockito.dart' as _i1; + +// ignore_for_file: type=lint +// ignore_for_file: avoid_redundant_argument_values +// ignore_for_file: avoid_setters_without_getters +// ignore_for_file: comment_references +// ignore_for_file: implementation_imports +// ignore_for_file: invalid_use_of_visible_for_testing_member +// ignore_for_file: prefer_const_constructors +// ignore_for_file: unnecessary_parenthesis +// ignore_for_file: camel_case_types +// ignore_for_file: subtype_of_sealed_class + +class _FakeCacheObject_0 extends _i1.SmartFake implements _i2.CacheObject { + _FakeCacheObject_0( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDuration_1 extends _i1.SmartFake implements Duration { + _FakeDuration_1( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFileSystem_2 extends _i1.SmartFake implements _i3.FileSystem { + _FakeFileSystem_2( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeDateTime_3 extends _i1.SmartFake implements DateTime { + _FakeDateTime_3( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFileServiceResponse_4 extends _i1.SmartFake + implements _i4.FileServiceResponse { + _FakeFileServiceResponse_4( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +class _FakeFileService_5 extends _i1.SmartFake implements _i4.FileService { + _FakeFileService_5( + Object parent, + Invocation parentInvocation, + ) : super( + parent, + parentInvocation, + ); +} + +/// A class which mocks [CacheInfoRepository]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCacheInfoRepositoryBase extends _i1.Mock + implements _i4.CacheInfoRepository { + MockCacheInfoRepositoryBase() { + _i1.throwOnMissingStub(this); + } + + @override + _i5.Future exists() => (super.noSuchMethod( + Invocation.method( + #exists, + [], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); + @override + _i5.Future open() => (super.noSuchMethod( + Invocation.method( + #open, + [], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); + @override + _i5.Future updateOrInsert(_i2.CacheObject? cacheObject) => + (super.noSuchMethod( + Invocation.method( + #updateOrInsert, + [cacheObject], + ), + returnValue: _i5.Future.value(), + ) as _i5.Future); + @override + _i5.Future<_i2.CacheObject> insert( + _i2.CacheObject? cacheObject, { + bool? setTouchedToNow = true, + }) => + (super.noSuchMethod( + Invocation.method( + #insert, + [cacheObject], + {#setTouchedToNow: setTouchedToNow}, + ), + returnValue: _i5.Future<_i2.CacheObject>.value(_FakeCacheObject_0( + this, + Invocation.method( + #insert, + [cacheObject], + {#setTouchedToNow: setTouchedToNow}, + ), + )), + ) as _i5.Future<_i2.CacheObject>); + @override + _i5.Future<_i2.CacheObject?> get(String? key) => (super.noSuchMethod( + Invocation.method( + #get, + [key], + ), + returnValue: _i5.Future<_i2.CacheObject?>.value(), + ) as _i5.Future<_i2.CacheObject?>); + @override + _i5.Future delete(int? id) => (super.noSuchMethod( + Invocation.method( + #delete, + [id], + ), + returnValue: _i5.Future.value(0), + ) as _i5.Future); + @override + _i5.Future deleteAll(Iterable? ids) => (super.noSuchMethod( + Invocation.method( + #deleteAll, + [ids], + ), + returnValue: _i5.Future.value(0), + ) as _i5.Future); + @override + _i5.Future update( + _i2.CacheObject? cacheObject, { + bool? setTouchedToNow = true, + }) => + (super.noSuchMethod( + Invocation.method( + #update, + [cacheObject], + {#setTouchedToNow: setTouchedToNow}, + ), + returnValue: _i5.Future.value(0), + ) as _i5.Future); + @override + _i5.Future> getAllObjects() => (super.noSuchMethod( + Invocation.method( + #getAllObjects, + [], + ), + returnValue: + _i5.Future>.value(<_i2.CacheObject>[]), + ) as _i5.Future>); + @override + _i5.Future> getObjectsOverCapacity(int? capacity) => + (super.noSuchMethod( + Invocation.method( + #getObjectsOverCapacity, + [capacity], + ), + returnValue: + _i5.Future>.value(<_i2.CacheObject>[]), + ) as _i5.Future>); + @override + _i5.Future> getOldObjects(Duration? maxAge) => + (super.noSuchMethod( + Invocation.method( + #getOldObjects, + [maxAge], + ), + returnValue: + _i5.Future>.value(<_i2.CacheObject>[]), + ) as _i5.Future>); + @override + _i5.Future close() => (super.noSuchMethod( + Invocation.method( + #close, + [], + ), + returnValue: _i5.Future.value(false), + ) as _i5.Future); + @override + _i5.Future deleteDataFile() => (super.noSuchMethod( + Invocation.method( + #deleteDataFile, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); +} + +/// A class which mocks [CacheStore]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockCacheStoreBase extends _i1.Mock implements _i6.CacheStore { + MockCacheStoreBase() { + _i1.throwOnMissingStub(this); + } + + @override + Duration get cleanupRunMinInterval => (super.noSuchMethod( + Invocation.getter(#cleanupRunMinInterval), + returnValue: _FakeDuration_1( + this, + Invocation.getter(#cleanupRunMinInterval), + ), + ) as Duration); + @override + set cleanupRunMinInterval(Duration? _cleanupRunMinInterval) => + super.noSuchMethod( + Invocation.setter( + #cleanupRunMinInterval, + _cleanupRunMinInterval, + ), + returnValueForMissingStub: null, + ); + @override + _i3.FileSystem get fileSystem => (super.noSuchMethod( + Invocation.getter(#fileSystem), + returnValue: _FakeFileSystem_2( + this, + Invocation.getter(#fileSystem), + ), + ) as _i3.FileSystem); + @override + set fileSystem(_i3.FileSystem? _fileSystem) => super.noSuchMethod( + Invocation.setter( + #fileSystem, + _fileSystem, + ), + returnValueForMissingStub: null, + ); + @override + DateTime get lastCleanupRun => (super.noSuchMethod( + Invocation.getter(#lastCleanupRun), + returnValue: _FakeDateTime_3( + this, + Invocation.getter(#lastCleanupRun), + ), + ) as DateTime); + @override + set lastCleanupRun(DateTime? _lastCleanupRun) => super.noSuchMethod( + Invocation.setter( + #lastCleanupRun, + _lastCleanupRun, + ), + returnValueForMissingStub: null, + ); + @override + String get storeKey => (super.noSuchMethod( + Invocation.getter(#storeKey), + returnValue: '', + ) as String); + @override + _i5.Future<_i4.FileInfo?> getFile( + String? key, { + bool? ignoreMemCache = false, + }) => + (super.noSuchMethod( + Invocation.method( + #getFile, + [key], + {#ignoreMemCache: ignoreMemCache}, + ), + returnValue: _i5.Future<_i4.FileInfo?>.value(), + ) as _i5.Future<_i4.FileInfo?>); + @override + _i5.Future putFile(_i2.CacheObject? cacheObject) => (super.noSuchMethod( + Invocation.method( + #putFile, + [cacheObject], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override + _i5.Future<_i2.CacheObject?> retrieveCacheData( + String? key, { + bool? ignoreMemCache = false, + }) => + (super.noSuchMethod( + Invocation.method( + #retrieveCacheData, + [key], + {#ignoreMemCache: ignoreMemCache}, + ), + returnValue: _i5.Future<_i2.CacheObject?>.value(), + ) as _i5.Future<_i2.CacheObject?>); + @override + _i5.Future<_i4.FileInfo?> getFileFromMemory(String? key) => + (super.noSuchMethod( + Invocation.method( + #getFileFromMemory, + [key], + ), + returnValue: _i5.Future<_i4.FileInfo?>.value(), + ) as _i5.Future<_i4.FileInfo?>); + @override + _i5.Future emptyCache() => (super.noSuchMethod( + Invocation.method( + #emptyCache, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override + void emptyMemoryCache() => super.noSuchMethod( + Invocation.method( + #emptyMemoryCache, + [], + ), + returnValueForMissingStub: null, + ); + @override + _i5.Future removeCachedFile(_i2.CacheObject? cacheObject) => + (super.noSuchMethod( + Invocation.method( + #removeCachedFile, + [cacheObject], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); + @override + _i5.Future dispose() => (super.noSuchMethod( + Invocation.method( + #dispose, + [], + ), + returnValue: _i5.Future.value(), + returnValueForMissingStub: _i5.Future.value(), + ) as _i5.Future); +} + +/// A class which mocks [FileService]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockFileServiceBase extends _i1.Mock implements _i4.FileService { + MockFileServiceBase() { + _i1.throwOnMissingStub(this); + } + + @override + int get concurrentFetches => (super.noSuchMethod( + Invocation.getter(#concurrentFetches), + returnValue: 0, + ) as int); + @override + set concurrentFetches(int? _concurrentFetches) => super.noSuchMethod( + Invocation.setter( + #concurrentFetches, + _concurrentFetches, + ), + returnValueForMissingStub: null, + ); + @override + _i5.Future<_i4.FileServiceResponse> get( + String? url, { + Map? headers, + }) => + (super.noSuchMethod( + Invocation.method( + #get, + [url], + {#headers: headers}, + ), + returnValue: _i5.Future<_i4.FileServiceResponse>.value( + _FakeFileServiceResponse_4( + this, + Invocation.method( + #get, + [url], + {#headers: headers}, + ), + )), + ) as _i5.Future<_i4.FileServiceResponse>); +} + +/// A class which mocks [WebHelper]. +/// +/// See the documentation for Mockito's code generation for more information. +class MockWebHelper extends _i1.Mock implements _i7.WebHelper { + MockWebHelper() { + _i1.throwOnMissingStub(this); + } + + @override + _i4.FileService get fileFetcher => (super.noSuchMethod( + Invocation.getter(#fileFetcher), + returnValue: _FakeFileService_5( + this, + Invocation.getter(#fileFetcher), + ), + ) as _i4.FileService); + @override + int get concurrentCalls => (super.noSuchMethod( + Invocation.getter(#concurrentCalls), + returnValue: 0, + ) as int); + @override + set concurrentCalls(int? _concurrentCalls) => super.noSuchMethod( + Invocation.setter( + #concurrentCalls, + _concurrentCalls, + ), + returnValueForMissingStub: null, + ); + @override + _i5.Stream<_i4.FileResponse> downloadFile( + String? url, { + String? key, + Map? authHeaders, + bool? ignoreMemCache = false, + }) => + (super.noSuchMethod( + Invocation.method( + #downloadFile, + [url], + { + #key: key, + #authHeaders: authHeaders, + #ignoreMemCache: ignoreMemCache, + }, + ), + returnValue: _i5.Stream<_i4.FileResponse>.empty(), + ) as _i5.Stream<_i4.FileResponse>); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/repositories/json_file_repository_test.dart b/ohos/test_flutter_cache_manager/lib/src/repositories/json_file_repository_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..44769aaa89b9bb2a0b2fa54f6b6bb0a85e580006 --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/repositories/json_file_repository_test.dart @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/src/storage/cache_info_repositories/json_cache_info_repository.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:test_flutter_cache_manager/common/test_page.dart'; + +import '../helpers/json_repo_helpers.dart'; + +class JsonCacheInfoRepositoryTestPage extends TestPage { + JsonCacheInfoRepositoryTestPage(String title, {Key? key}) + : super(title: title, key: key) { + group('创建存储库', () { + test('使用数据库名称创建存储库成功', () { + var repository = JsonCacheInfoRepository(databaseName: databaseName); + expect(repository != null, true); + }); + + test('成功创建指定路径的存储库', () { + var repository = JsonCacheInfoRepository(path: path); + expect(repository != null, true); + }); + + test('使用路径和databaseName创建存储库引发断言错误', () { + JsonCacheInfoRepository( + path: path, + databaseName: databaseName, + ); + }); + + test('使用目录创建存储库成功', () { + var repository = JsonCacheInfoRepository.withFile(File(path)); + expect(repository != null, true); + }); + }); + + group('打开和关闭存储库', () { + test('打开存储库 JsonCacheInfoRepository.withFile.open', () async { + var repository = JsonCacheInfoRepository.withFile(File(path)); + await repository.open(); + }); + + test('关闭存储库 JsonRepoHelpers.createRepository.close', () async { + var repository = await JsonRepoHelpers.createRepository(); + var isClosed = await repository.close(); + expect(isClosed, true); + }); + + test('重复关闭存储库', () async { + var repository = await JsonRepoHelpers.createRepository(); + await repository.open(); + var isClosed = await repository.close(); + expect(isClosed, false); + isClosed = await repository.close(); + expect(isClosed, true); + }); + }); + + group('Exist and delete', () { + test('是否存在JsonCacheInfoRepository.withFile.exists', () async { + var repository = JsonCacheInfoRepository.withFile(File(path)); + var exists = await repository.exists(); + expect(exists, false); + + repository = await JsonRepoHelpers.createRepository(); + exists = await repository.exists(); + expect(exists, true); + }); + + test('JsonRepoHelpers.createRepository.deleteDataFile', () async { + var repository = await JsonRepoHelpers.createRepository(); + await repository.deleteDataFile(); + var exists = await repository.exists(); + expect(exists, false); + }); + }); + + group('Get', () { + test('JsonRepoHelpers.createRepository.get', () async { + var repo = await JsonRepoHelpers.createRepository(); + var result = await repo.get(testurl); + expect(result != null, true); + + repo = await JsonRepoHelpers.createRepository(); + result = await repo.get('not an url'); + expect(result == null, true); + }); + + test('JsonRepoHelpers.createRepository.getAllObjects', () async { + var repo = await JsonRepoHelpers.createRepository(); + var result = await repo.getAllObjects(); + expect(result.length, JsonRepoHelpers.startCacheObjects.length); + }); + + test('JsonRepoHelpers.createRepository.getObjectsOverCapacity', () async { + var repo = await JsonRepoHelpers.createRepository(); + var result = await repo.getObjectsOverCapacity(1); + expect(result.length, 2); + expectIdInList(result, 1); + expectIdInList(result, 3); + + repo = await JsonRepoHelpers.createRepository(); + result = await repo.getOldObjects(const Duration(days: 7)); + expect(result.length, 1); + }); + }); + + group('update and insert', () { + test('JsonRepoHelpers.createRepository.insert', () async { + var repo = await JsonRepoHelpers.createRepository(); + var objectToInsert = JsonRepoHelpers.extraCacheObject; + var insertedObject = + await repo.insert(JsonRepoHelpers.extraCacheObject); + expect(insertedObject.id, JsonRepoHelpers.startCacheObjects.length + 1); + expect(insertedObject.url, objectToInsert.url); + expect(insertedObject.touched != null, true); + + var allObjects = await repo.getAllObjects(); + var newObject = + allObjects.where((element) => element.id == insertedObject.id); + expect(newObject != null, true); + }); + + test('insert throws when adding existing object', () async { + var repo = await JsonRepoHelpers.createRepository(); + var objectToInsert = JsonRepoHelpers.startCacheObjects.first; + repo.insert(objectToInsert); + }); + + test('JsonRepoHelpers.createRepository.update', () async { + var repo = await JsonRepoHelpers.createRepository(); + var objectToInsert = JsonRepoHelpers.startCacheObjects.first; + var newUrl = 'newUrl.com'; + var updatedObject = objectToInsert.copyWith(url: newUrl); + await repo.update(updatedObject); + var retrievedObject = await repo.get(objectToInsert.key); + expect(retrievedObject!.url, newUrl); + }); + + test('JsonRepoHelpers.createRepository.extraCacheObject', () async { + var repo = await JsonRepoHelpers.createRepository(); + var newObject = JsonRepoHelpers.extraCacheObject; + repo.update(newObject); + }); + + test('JsonRepoHelpers.createRepository.get', () async { + var repo = await JsonRepoHelpers.createRepository(); + var objectToInsert = JsonRepoHelpers.startCacheObjects.first; + var newUrl = 'newUrl.com'; + var updatedObject = objectToInsert.copyWith(url: newUrl); + await repo.updateOrInsert(updatedObject); + var retrievedObject = await repo.get(objectToInsert.key); + expect(retrievedObject!.url, newUrl); + }); + + test('JsonRepoHelpers.createRepository.updateOrInsert', () async { + var repo = await JsonRepoHelpers.createRepository(); + var objectToInsert = JsonRepoHelpers.extraCacheObject; + var insertedObject = + await repo.updateOrInsert(JsonRepoHelpers.extraCacheObject); + expect(insertedObject.id, JsonRepoHelpers.startCacheObjects.length + 1); + expect(insertedObject.url, objectToInsert.url); + expect(insertedObject.touched != null, true); + + var allObjects = await repo.getAllObjects(); + var newObject = + allObjects.where((element) => element.id == insertedObject.id); + expect(newObject != null, true); + }); + }); + + group('delete', () { + test('JsonRepoHelpers.createRepository.delete', () async { + var removedId = 2; + var repo = await JsonRepoHelpers.createRepository(); + var deleted = await repo.delete(removedId); + expect(deleted, 1); + var objects = await repo.getAllObjects(); + var removedObject = objects.where((element) => element.id == removedId); + expect(removedObject.length, 0); + expect(objects.length, JsonRepoHelpers.startCacheObjects.length - 1); + }); + + test('JsonRepoHelpers.createRepository.deleteAll', () async { + var removedIds = [2, 3]; + var repo = await JsonRepoHelpers.createRepository(); + var deleted = await repo.deleteAll(removedIds); + expect(deleted, 2); + var objects = await repo.getAllObjects(); + var removedObject = + objects.where((element) => removedIds.contains(element.id)); + expect(removedObject.length, 0); + expect(objects.length, + JsonRepoHelpers.startCacheObjects.length - removedIds.length); + + var removedId = 99; + repo = await JsonRepoHelpers.createRepository(); + deleted = await repo.delete(removedId); + expect(deleted, 0); + }); + }); + } +} + +void expectIdInList(List cacheObjects, int id) { + var object = cacheObjects.singleWhereOrNull((element) => element.id == id); + expect(object != null, true); +} diff --git a/ohos/test_flutter_cache_manager/lib/src/repositories/migration_test.dart b/ohos/test_flutter_cache_manager/lib/src/repositories/migration_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..2778931e674620790122919b256905596cb7a0ff --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/repositories/migration_test.dart @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:collection/collection.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/storage/cache_object.dart'; +import 'package:matcher/src/interfaces.dart'; +import 'package:mockito/mockito.dart'; +import 'package:test_flutter_cache_manager/common/test_page.dart'; + +import '../helpers/json_repo_helpers.dart' show JsonRepoHelpers; +import '../helpers/mock_cache_info_repository.dart'; + +class MigrationTestPage extends TestPage { + MigrationTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('迁移测试', () { + test('文件添加到新存储库中', () async { + var mockRepo = setupMockRepo(false); + var source = await JsonRepoHelpers.createRepository(open: false); + await mockRepo.migrateFrom(source); + for (var object in JsonRepoHelpers.startCacheObjects) { + verify( + mockRepo.insert( + argThat(CacheObjectMatcher(object)), + setTouchedToNow: anyNamed('setTouchedToNow'), + ), + ); + } + }); + + test('旧存储已删除', () async { + var mockRepo = setupMockRepo(false); + var source = await JsonRepoHelpers.createRepository(open: false); + await mockRepo.migrateFrom(source); + var exists = await source.exists(); + expect(exists, false); + }); + + test('在现有存储中更新文件', () async { + var mockRepo = setupMockRepo(true); + var source = await JsonRepoHelpers.createRepository(open: false); + await mockRepo.migrateFrom(source); + for (var object in JsonRepoHelpers.startCacheObjects) { + verify( + mockRepo.update( + argThat(CacheObjectMatcher(object)), + setTouchedToNow: anyNamed('setTouchedToNow'), + ), + ); + } + }); + }); + } +} + +MockCacheInfoRepository setupMockRepo(bool returnObjects) { + var mockRepo = MockCacheInfoRepository(); + when(mockRepo.get(any)).thenAnswer((realInvocation) { + if (!returnObjects) return Future.value(null); + var key = realInvocation.positionalArguments.first as String; + var cacheObject = JsonRepoHelpers.startCacheObjects.firstWhereOrNull( + (element) => element.key == key, + ); + return Future.value(cacheObject); + }); + when(mockRepo.insert(any)).thenAnswer((realInvocation) => Future.value(realInvocation.positionalArguments.first as CacheObject)); + return mockRepo; +} + +class CacheObjectMatcher extends Matcher { + final CacheObject value; + static final Object _mismatchedValueKey = Object(); + + CacheObjectMatcher(this.value); + + @override + Description describe(Description description) { + description.add('Matches cacheObject $value'); + return description; + } + + @override + bool matches(item, Map matchState) { + var isMatch = false; + if (item is CacheObject) { + isMatch = item.key == value.key && + item.url == value.url && + item.relativePath == value.relativePath && + item.length == value.length && + item.touched!.millisecondsSinceEpoch == value.touched!.millisecondsSinceEpoch && + item.eTag == value.eTag; + } + if (!isMatch) matchState[_mismatchedValueKey] = item; + return isMatch; + } + + @override + Description describeMismatch( + dynamic item, + Description mismatchDescription, + Map matchState, + bool verbose, + ) { + if (matchState.containsKey(_mismatchedValueKey)) { + final actualValue = matchState[_mismatchedValueKey] as CacheObject; + // Leading whitespace is added so that lines in the multiline + // description returned by addDescriptionOf are all indented equally + // which makes the output easier to read for this case. + return mismatchDescription + .add('expected normalized value\n ') + .addDescriptionOf('${value.key}: ${value.url}') + .add('\nbut got\n ') + .addDescriptionOf('${actualValue.key}: ${actualValue.url}'); + } + return mismatchDescription; + } +} diff --git a/ohos/test_flutter_cache_manager/lib/src/web_helper_test.dart b/ohos/test_flutter_cache_manager/lib/src/web_helper_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f5901f96245b12b2148c02a775c31ea9b3f090ca --- /dev/null +++ b/ohos/test_flutter_cache_manager/lib/src/web_helper_test.dart @@ -0,0 +1,258 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; +import 'package:flutter_cache_manager/flutter_cache_manager.dart'; +import 'package:flutter_cache_manager/src/cache_store.dart'; +import 'package:flutter_cache_manager/src/web/web_helper.dart'; +import 'package:mockito/mockito.dart'; +import 'package:test_flutter_cache_manager/common/test_page.dart'; + +import 'helpers/config_extensions.dart'; +import 'helpers/mock_cache_store.dart'; +import 'helpers/mock_file_fetcher_response.dart'; +import 'helpers/mock_file_service.dart'; +import 'helpers/test_configuration.dart'; + +class WebHelperTestPage extends TestPage { + WebHelperTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('测试状态码', () { + test('返回200正常', () async { + const imageUrl = 'baseflow.com/testimage'; + + var config = createTestConfig(); + var store = CacheStore(config); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([0, 1, 2, 3, 4, 5]), + 0, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + var result = await webHelper + .downloadFile(imageUrl) + .firstWhere((r) => r is FileInfo, orElse: null); + result; + }); + + test('404 异常', () async { + const imageUrl = 'baseflow.com/testimage'; + + var config = createTestConfig(); + var store = CacheStore(config); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([]), 0, null, '', 404, DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + + expect(webHelper.downloadFile(imageUrl).toList(), + (e) => e is HttpExceptionWithStatus && e.statusCode == 404); + }); + + test('304忽略内容', () async { + const imageUrl = 'baseflow.com/testimage'; + + var config = createTestConfig(); + var store = CacheStore(config); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([]), 0, 'testv1', '.jpg', 304, DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + var result = await webHelper + .downloadFile(imageUrl) + .firstWhere((r) => r is FileInfo, orElse: null); + result; + }); + }); + + group('Parallel logic', () { + test('重复调用WebHelper', () async { + const imageUrl = 'baseflow.com/testimage'; + + var config = createTestConfig(); + var store = _createStore(config); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([0, 1, 2, 3, 4, 5]), + 6, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + + var call1 = webHelper.downloadFile(imageUrl).toList(); + var call2 = webHelper.downloadFile(imageUrl).toList(); + await Future.wait([call1, call2]); + + verify(store.retrieveCacheData(any)); + }); + + test('当memcache被忽略时,调用webhelper两次会超过两次', + () async { + const imageUrl = 'baseflow.com/testimage'; + + var config = createTestConfig(); + var store = _createStore(config); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([0, 1, 2, 3, 4, 5]), + 6, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + var call1 = webHelper.downloadFile(imageUrl).toList(); + var call2 = + webHelper.downloadFile(imageUrl, ignoreMemCache: true).toList(); + await Future.wait([call1, call2]); + + verify(store.retrieveCacheData(any)); + }); + + test('并发调用', () async { + const url1 = 'baseflow.com/testimage1'; + const url2 = 'baseflow.com/testimage2'; + const url3 = 'baseflow.com/testimage3'; + + var config = createTestConfig(); + var store = _createStore(config); + final fileService = MockFileService(); + + var completer1 = Completer(); + var completer2 = Completer(); + var completer3 = Completer(); + + when(fileService.get(url1, headers: anyNamed('headers'))) + .thenAnswer((realInvocation) => completer1.future); + when(fileService.get(url2, headers: anyNamed('headers'))) + .thenAnswer((realInvocation) => completer2.future); + when(fileService.get(url3, headers: anyNamed('headers'))) + .thenAnswer((realInvocation) => completer3.future); + + var webHelper = WebHelper(store, fileService); + webHelper.downloadFile(url1); + webHelper.downloadFile(url2); + webHelper.downloadFile(url3); + + await Future.delayed(const Duration(microseconds: 1)); + + verify(fileService.get(url1, headers: anyNamed('headers'))); + verify(fileService.get(url2, headers: anyNamed('headers'))); + verifyNever(fileService.get(url3, headers: anyNamed('headers'))); + + completer1.complete(MockFileFetcherResponse.basic()); + + await Future.delayed(const Duration(microseconds: 1)); + verify(fileService.get(url3, headers: anyNamed('headers'))); + }); + }); + + group('Miscellaneous', () { + test('当尚未缓存时,应创建新的cacheobject', () async { + const imageUrl = 'baseflow.com/testimage'; + const fileName = 'testv1.jpg'; + final validTill = DateTime.now(); + + var config = createTestConfig(); + var store = _createStore(config); + config.returnsCacheObject(imageUrl, fileName, validTill); + + final fileService = MockFileService(); + when(fileService.get(imageUrl, headers: anyNamed('headers'))) + .thenAnswer((_) { + return Future.value(MockFileFetcherResponse( + Stream.value([0, 1, 2, 3, 4, 5]), + 6, + 'testv1', + '.jpg', + 200, + DateTime.now())); + }); + + var webHelper = WebHelper(store, fileService); + var result = await webHelper + .downloadFile(imageUrl) + .firstWhere((r) => r is FileInfo, orElse: null); + result; + verify(store.putFile(any)); + }); + + test('如果扩展名更改,则应删除文件', () async { + const imageUrl = 'baseflow.com/testimage'; + var imageName = 'image.png'; + + var config = createTestConfig(); + var store = CacheStore(config); + var file = await config.returnsFile(imageName); + config.returnsCacheObject(imageUrl, imageName, DateTime.now()); + + final fileService = MockFileService(); + var webHelper = WebHelper(store, fileService); + + expect(await file.exists(), true); + var _ = await webHelper + .downloadFile(imageUrl) + .firstWhere((r) => r is FileInfo, orElse: null); + expect(await file.exists(), false); + }); + }); + } +} + +MockCacheStore _createStore(Config config) { + final store = MockCacheStore(); + // when(store.putFile(argThat(null))).thenAnswer((_) => Future.value()); + // when(store.retrieveCacheData(argThat(anything))) + // .thenAnswer((invocation) => Future.value(CacheObject( + // invocation.positionalArguments.first as String, + // relativePath: 'test.png', + // validTill: clock.now().add(const Duration(days: 7)), + // ))); + when(store.fileSystem).thenReturn(config.fileSystem); + return store; +} + +class MockStore extends Mock implements CacheStore {} diff --git a/ohos/test_flutter_cache_manager/ohos/.gitignore b/ohos/test_flutter_cache_manager/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/AppScope/app.json5 b/ohos/test_flutter_cache_manager/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..36ea350903b7d882911a6d68f25910ea2d0f4c1f --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_flutter_cache_manager", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/element/string.json b/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..0040d9a7c161e04dcba2dc63b4e76151d51589f9 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_flutter_cache_manager" + } + ] +} diff --git a/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_flutter_cache_manager/ohos/build-profile.json5 b/ohos/test_flutter_cache_manager/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2fe910af8e453b9c0ab0e73722bed4af65c540e0 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_flutter_cache_manager.cer", + "storePassword": "0000001A9CE599A05C175E260F83BC4263AB0D6824F55F7F7470A434AE498E610E0F29C0CFFA5DA0953A", + "keyAlias": "debugKey", + "keyPassword": "0000001A72292331887E1AD9D42BF70C2ACF1D056FF5EE8A3B83B796A1A35EBFB18F231B44149B050F42", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_flutter_cache_manager.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_flutter_cache_manager.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_flutter_cache_manager/ohos/dependencies/rollup.tgz b/ohos/test_flutter_cache_manager/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_flutter_cache_manager/ohos/dta/icudtl.dat b/ohos/test_flutter_cache_manager/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/dta/icudtl.dat differ diff --git a/ohos/test_flutter_cache_manager/ohos/entry/.gitignore b/ohos/test_flutter_cache_manager/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/build-profile.json5 b/ohos/test_flutter_cache_manager/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/hvigorfile.ts b/ohos/test_flutter_cache_manager/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_flutter_cache_manager/ohos/entry/oh-package.json5 b/ohos/test_flutter_cache_manager/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..716467d67dec8d9c08cc10e9552b99052a8539cd --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/oh-package.json5 @@ -0,0 +1,13 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har", + "@ohos/path_provider": "file:../har/path_provider.har" + } +} diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..8789ad56e6b61c40a4fa334fdc3690ef5be14a45 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import PathProviderPlugin from '@ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + this.addPlugin(new PathProviderPlugin()) + } +} diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/module.json5 b/ohos/test_flutter_cache_manager/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/module.json5 b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.10 b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.9 b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.debug.10 b/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.release.10 b/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_flutter_cache_manager/ohos/har/path_provider.har b/ohos/test_flutter_cache_manager/ohos/har/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..8c59d9becc7b85514cdf262b804216c32a856cbb Binary files /dev/null and b/ohos/test_flutter_cache_manager/ohos/har/path_provider.har differ diff --git a/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-config.json5 b/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-wrapper.js b/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/hvigorfile.ts b/ohos/test_flutter_cache_manager/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/hvigorw b/ohos/test_flutter_cache_manager/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_flutter_cache_manager/ohos/hvigorw.bat b/ohos/test_flutter_cache_manager/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_flutter_cache_manager/ohos/oh-package-lock.json5 b/ohos/test_flutter_cache_manager/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_flutter_cache_manager/ohos/oh-package.json5 b/ohos/test_flutter_cache_manager/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_flutter_cache_manager/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_flutter_cache_manager/package-lock.json b/ohos/test_flutter_cache_manager/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..901dbc8bc50c9ede0494f54eb0ac99e4298cb2d6 --- /dev/null +++ b/ohos/test_flutter_cache_manager/package-lock.json @@ -0,0 +1,6 @@ +{ + "name": "test_flutter_cache_manager", + "lockfileVersion": 2, + "requires": true, + "packages": {} +} diff --git a/ohos/test_flutter_cache_manager/pubspec.yaml b/ohos/test_flutter_cache_manager/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..b0ea8ecb966dafb06a71e97b204473bcbf080efe --- /dev/null +++ b/ohos/test_flutter_cache_manager/pubspec.yaml @@ -0,0 +1,41 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_flutter_cache_manager +description: A new Flutter project. +publish_to: none +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + cupertino_icons: ^1.0.5 + flutter: + sdk: flutter + url_launcher: ^6.1.10 + flutter_cache_manager: 3.3.1 + mockito: ^5.0.0 + dio: ^5.3.3 + path_provider_platform_interface: ^2.0.0 + path_provider_ohos: + path: ./lib/path_provider_ohos +flutter: + uses-material-design: true + assets: + - assets/image-120.png +dev_dependencies: + flutter_lints: + flutter_test: + sdk: flutter \ No newline at end of file diff --git a/ohos/test_octo_image/.gitignore b/ohos/test_octo_image/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_octo_image/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_octo_image/.metadata b/ohos/test_octo_image/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_octo_image/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_octo_image/README.md b/ohos/test_octo_image/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_octo_image/analysis_options.yaml b/ohos/test_octo_image/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_octo_image/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_octo_image/lib/helpers/mock_image_provider.dart b/ohos/test_octo_image/lib/helpers/mock_image_provider.dart new file mode 100644 index 0000000000000000000000000000000000000000..9ca8559cb17765f0d3c4f3ef6ae4455dfd786413 --- /dev/null +++ b/ohos/test_octo_image/lib/helpers/mock_image_provider.dart @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:ui' as ui show Codec, ImageDecoderCallback; +import 'dart:ui'; +import 'package:flutter/painting.dart'; +import 'package:flutter/services.dart'; +import 'package:http/http.dart' as http; +import 'package:flutter/foundation.dart'; + +enum TestUseCase { + loadAndFail, + loadAndSuccess, + success, +} + +@immutable +class MockImageProvider extends ImageProvider { + final _timeStamp = DateTime.now().millisecondsSinceEpoch; + MockImageProvider({ + required this.useCase, + }); + + final TestUseCase useCase; + + bool get showLoading => + useCase == TestUseCase.loadAndFail || + useCase == TestUseCase.loadAndSuccess; + + bool get fail => useCase == TestUseCase.loadAndFail; + + @override + Future obtainKey(ImageConfiguration configuration) { + return SynchronousFuture(this); + } + + @override + ImageStreamCompleter loadImage( + MockImageProvider key, ui.ImageDecoderCallback decode) { + final chunkEvents = StreamController(); + return MultiFrameImageStreamCompleter( + codec: _loadAsync(key, chunkEvents, decode).first, + chunkEvents: chunkEvents.stream, + scale: 1.0, + ); + } + + Stream _loadAsync( + MockImageProvider key, + StreamController chunkEvents, + ui.ImageDecoderCallback decode, + ) async* { + try { + if (showLoading) { + var totalSize = 100; + for (var i = 0; i < totalSize; i++) { + await Future.delayed(const Duration(milliseconds: 10)); + chunkEvents.add(ImageChunkEvent( + cumulativeBytesLoaded: i + 1, expectedTotalBytes: totalSize)); + } + } + if (fail) { + throw Exception("Image loading failed"); + } + var url = 'http://blurha.sh/assets/images/img1.jpg'; + Uint8List imageBytes; + imageBytes = (await http.get(Uri.parse(url))).bodyBytes; + final buffer = await ImmutableBuffer.fromUint8List(imageBytes); + decode(buffer as Image); + // yield decodedImage; + } finally { + await chunkEvents.close(); + } + } + + @override + bool operator ==(dynamic other) { + if (other is MockImageProvider) { + return useCase == other.useCase && _timeStamp == other._timeStamp; + } + return false; + } + + @override + int get hashCode => useCase.hashCode; + + @override + String toString() => '$runtimeType("$useCase")'; +} diff --git a/ohos/test_octo_image/lib/main.dart b/ohos/test_octo_image/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..935f92b63af1d54e8c10ff360db4421a2afb8239 --- /dev/null +++ b/ohos/test_octo_image/lib/main.dart @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:octo_image/octo_image.dart'; + +void main() { + WidgetsFlutterBinding.ensureInitialized(); + HttpOverrides.global = GlobalHttpOverrides(); + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'OctoImage Demo', + theme: ThemeData(), + home: const OctoImagePage(), + ); + } +} + +class OctoImagePage extends StatelessWidget { + const OctoImagePage({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('OctoImage Demo'), + ), + body: ListView( + children: [ + Text('下面是图片正在加载中用于自定义填充的转圈'), + _customImage(), + const SizedBox(height: 16), + Text('下面是图片加载错误时 octoSet 参数会进行自定义红底+M字, 上面一张为加载出错'), + _circleAvatar(getImageErr: true), + _circleAvatar(), + ], + ), + ); + } + + Widget _customImage() { + return SizedBox( + height: 150, + child: OctoImage( + image: const NetworkImage('http://via.placeholder.com/150'), + progressIndicatorBuilder: (context, progress) { + double? value; + var expectedBytes = progress?.expectedTotalBytes; + if (progress != null && expectedBytes != null) { + value = progress.cumulativeBytesLoaded / expectedBytes; + } + return CircularProgressIndicator(value: value); + }, + errorBuilder: (context, error, stacktrace) => const Icon(Icons.error), + ), + ); + } + + Widget _circleAvatar({bool getImageErr = false}) { + return SizedBox( + height: 75, + child: OctoImage.fromSet( + fit: BoxFit.cover, + image: NetworkImage(getImageErr + ? 'http://upload.wikimedia.org/wikipedia/commons/thumb/4/4e/Macaca_nigra_self-portrait_large.jpg/1024px-Macaca_nigra_self-portrait_large.jpg' + : 'http://img2.baidu.com/it/u=3456583680,520701261&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=500'), + octoSet: OctoSet.circleAvatar( + backgroundColor: Colors.red, + text: const Text("M"), + ), + ), + ); + } +} + +class GlobalHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + // TODO: implement createHttpClient + return super.createHttpClient(context)..badCertificateCallback = (X509Certificate cert, String host, int port) => true; + } +} diff --git a/ohos/test_octo_image/lib/main_sets.dart b/ohos/test_octo_image/lib/main_sets.dart new file mode 100644 index 0000000000000000000000000000000000000000..46ce7984b62a1d4b6d7b214aa7905449953e1116 --- /dev/null +++ b/ohos/test_octo_image/lib/main_sets.dart @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:octo_image/octo_image.dart'; + +import 'helpers/mock_image_provider.dart'; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({Key? key}) : super(key: key); + + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Set Demo', + theme: ThemeData(), + home: OctoImagePage( + sets: [ + OctoSet.circleAvatar( + backgroundColor: Colors.red, + text: const Text( + "M", + style: TextStyle(fontWeight: FontWeight.bold), + ), + ), + OctoSet.circularIndicatorAndIcon(), + OctoSet.circularIndicatorAndIcon(showProgress: true), + ], + ), + ); + } +} + +class OctoImagePage extends StatelessWidget { + final List sets; + + const OctoImagePage({Key? key, required this.sets}) : super(key: key); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Set Demo'), + ), + body: ListView(children: sets.map((element) => _row(element)).toList()), + ); + } + + Widget _row(OctoSet octoSet) { + return Row( + children: [ + Expanded( + child: AspectRatio( + aspectRatio: 269 / 173, + child: OctoImage.fromSet( + image: MockImageProvider(useCase: TestUseCase.loadAndFail), + octoSet: octoSet, + fit: BoxFit.cover, + ), + ), + ), + Expanded( + child: AspectRatio( + aspectRatio: 269 / 173, + child: OctoImage.fromSet( + image: MockImageProvider(useCase: TestUseCase.loadAndSuccess), + octoSet: octoSet, + fit: BoxFit.cover, + ), + ), + ), + ], + ); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/AUTHORS b/ohos/test_octo_image/lib/path_provider_ohos/AUTHORS new file mode 100644 index 0000000000000000000000000000000000000000..493a0b4ef9c221331dc6b518b947e9e16f1e9ced --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/AUTHORS @@ -0,0 +1,66 @@ +# Below is a list of people and organizations that have contributed +# to the Flutter project. Names should be added to the list like so: +# +# Name/Organization + +Google Inc. +The Chromium Authors +German Saprykin +Benjamin Sauer +larsenthomasj@gmail.com +Ali Bitek +Pol Batlló +Anatoly Pulyaevskiy +Hayden Flinner +Stefano Rodriguez +Salvatore Giordano +Brian Armstrong +Paul DeMarco +Fabricio Nogueira +Simon Lightfoot +Ashton Thomas +Thomas Danner +Diego Velásquez +Hajime Nakamura +Tuyển Vũ Xuân +Miguel Ruivo +Sarthak Verma +Mike Diarmid +Invertase +Elliot Hesp +Vince Varga +Aawaz Gyawali +EUI Limited +Katarina Sheremet +Thomas Stockx +Sarbagya Dhaubanjar +Ozkan Eksi +Rishab Nayak +ko2ic +Jonathan Younger +Jose Sanchez +Debkanchan Samadder +Audrius Karosevicius +Lukasz Piliszczuk +SoundReply Solutions GmbH +Rafal Wachol +Pau Picas +Christian Weder +Alexandru Tuca +Christian Weder +Rhodes Davis Jr. +Luigi Agosti +Quentin Le Guennec +Koushik Ravikumar +Nissim Dsilva +Giancarlo Rocha +Ryo Miyake +Théo Champion +Kazuki Yamaguchi +Eitan Schwartz +Chris Rutkowski +Juan Alvarez +Aleksandr Yurkovskiy +Anton Borries +Alex Li +Rahul Raj <64.rahulraj@gmail.com> diff --git a/ohos/test_octo_image/lib/path_provider_ohos/CHANGELOG.md b/ohos/test_octo_image/lib/path_provider_ohos/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_octo_image/lib/path_provider_ohos/LICENSE b/ohos/test_octo_image/lib/path_provider_ohos/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..c6823b81eb845db89cee59cbbc7ee0b0b63d86ec --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/LICENSE @@ -0,0 +1,25 @@ +Copyright 2013 The Flutter Authors. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ohos/test_octo_image/lib/path_provider_ohos/README.md b/ohos/test_octo_image/lib/path_provider_ohos/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_octo_image/lib/path_provider_ohos/lib/messages.g.dart b/ohos/test_octo_image/lib/path_provider_ohos/lib/messages.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..1b378259bafe178d1a4dd67890d5db507346a9f3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/lib/messages.g.dart @@ -0,0 +1,203 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'dart:async'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +enum StorageDirectory { + root, + music, + podcasts, + ringtones, + alarms, + notifications, + pictures, + movies, + downloads, + dcim, + documents, +} + +class PathProviderApi { + /// Constructor for [PathProviderApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + PathProviderApi({BinaryMessenger? binaryMessenger}) + : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getTemporaryPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getTemporaryPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationSupportPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationDocumentsPath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getApplicationCachePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getApplicationCachePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(null) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future getExternalStoragePath() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePath', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0] as String?); + } + } + + Future> getExternalCachePaths() async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalCachePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } + + Future> getExternalStoragePaths( + StorageDirectory arg_directory) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_directory.index]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as List?)!.cast(); + } + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/lib/path_provider_ohos.dart b/ohos/test_octo_image/lib/path_provider_ohos/lib/path_provider_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..deac27a6bcd8a67c1711b989171cea65ca4611c7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/lib/path_provider_ohos.dart @@ -0,0 +1,102 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:path_provider_platform_interface/path_provider_platform_interface.dart'; +import 'messages.g.dart' as messages; + +messages.StorageDirectory _convertStorageDirectory( + StorageDirectory? directory) { + switch (directory) { + case null: + return messages.StorageDirectory.root; + case StorageDirectory.music: + return messages.StorageDirectory.music; + case StorageDirectory.podcasts: + return messages.StorageDirectory.podcasts; + case StorageDirectory.ringtones: + return messages.StorageDirectory.ringtones; + case StorageDirectory.alarms: + return messages.StorageDirectory.alarms; + case StorageDirectory.notifications: + return messages.StorageDirectory.notifications; + case StorageDirectory.pictures: + return messages.StorageDirectory.pictures; + case StorageDirectory.movies: + return messages.StorageDirectory.movies; + case StorageDirectory.downloads: + return messages.StorageDirectory.downloads; + case StorageDirectory.dcim: + return messages.StorageDirectory.dcim; + case StorageDirectory.documents: + return messages.StorageDirectory.documents; + } +} + +/// The OHOS implementation of [PathProviderPlatform]. +class PathProviderOhos extends PathProviderPlatform { + final messages.PathProviderApi _api = messages.PathProviderApi(); + + /// Registers this class as the default instance of [PathProviderPlatform]. + static void registerWith() { + PathProviderPlatform.instance = PathProviderOhos(); + } + + @override + Future getTemporaryPath() { + return _api.getTemporaryPath(); + } + + @override + Future getApplicationSupportPath() { + return _api.getApplicationSupportPath(); + } + + @override + Future getLibraryPath() { + throw UnsupportedError('getLibraryPath is not supported on OHOS'); + } + + @override + Future getApplicationDocumentsPath() { + return _api.getApplicationDocumentsPath(); + } + + @override + Future getApplicationCachePath() { + return _api.getApplicationCachePath(); + } + + @override + Future getExternalStoragePath() { + return _api.getExternalStoragePath(); + } + + @override + Future?> getExternalCachePaths() async { + return (await _api.getExternalCachePaths()).cast(); + } + + @override + Future?> getExternalStoragePaths({ + StorageDirectory? type, + }) async { + return (await _api.getExternalStoragePaths(_convertStorageDirectory(type))) + .cast(); + } + + @override + Future getDownloadsPath() { + throw UnsupportedError('getDownloadsPath is not supported on OHOS'); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..1e922e7e1fc28adb088df43e96d59e2e64598bf0 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/file-cache.json @@ -0,0 +1 @@ +{"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5":{"hashValue":"c5cbb5522de13fac82f033c7cd9b48d8","name":"app.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":226,"lastModifiedTime":1695632211627}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5":{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5":{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json":{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json":{"hashValue":"1c8e8a915a9b7f222d4cf94722d1bb42","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":491,"lastModifiedTime":1698044664928}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json":{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs":{"hashValue":"fb414dab48788ac59123df55cae63f0b","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"2a8cdcb7a112ce8f608fa4c5a8b26644","name":"flutter_ohos.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs\\flutter_ohos.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":19163432,"lastModifiedTime":1698044260416}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default":{"hashValue":"","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default","type":"directory","isSymbolicLink":false,"children":[]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources":{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default":{"hashValue":"76f5c8d078ca69ae9175830aa99a05dc","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f12d653569ed3cffc2c73dbcf141b3e7","name":"ids_map","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"fde1d32f9d3798179b3345d3d3b044a8","name":"id_defined.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":148,"lastModifiedTime":1698044665019}}]},{"hashValue":"2ed40cf3b6a0258fcf7ef0d5663211d7","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":652,"lastModifiedTime":1698044665018}},{"hashValue":"d1d25a5d183601133bbabec3842873ac","name":"resConfig.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1161,"lastModifiedTime":1697686151232}},{"hashValue":"98c2ba5b20a7da7409087b816f0988e8","name":"resources.index","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources.index","type":"file","isSymbolicLink":false,"fileMetaData":{"size":396,"lastModifiedTime":1698044665018}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h":{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default":{"hashValue":"93721c69ae9a43a6b6b026ce4ba28ad2","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d021dd9a3167074553dba4f2c5854465","name":"ResourceTable.h","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h","type":"file","isSymbolicLink":false,"fileMetaData":{"size":750,"lastModifiedTime":1698044665015}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default":{"hashValue":"de5eea44e80e5ff634766ec94c928117","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider":{"hashValue":"7190fb2c4d706ed6e0e4babda37414da","name":"path_provider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"dd38cfe42b111fd0bc58052c7bc17c51","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3a65d298f5e72b2d44c536dcdc681eab","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"1b4eb7b03f613b971199abeae1d7ad6d","name":"module.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":137,"lastModifiedTime":1695632211699}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt":{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar":{"hashValue":"77ec3ff3075d1e1b0f77eea3593fc54a","name":"default@PackageHar","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"34bdaa94e55567ca04e39d0ddc512301","name":"build-profile.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\build-profile.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":119,"lastModifiedTime":1695632211630}},{"hashValue":"19d5ec875e8653c8b6be599c08514ccb","name":"hvigorfile.ts","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\hvigorfile.ts","type":"file","isSymbolicLink":false,"fileMetaData":{"size":160,"lastModifiedTime":1695632211630}},{"hashValue":"","name":"libs","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\libs","type":"directory","isSymbolicLink":false,"children":[]},{"hashValue":"c55207f83ac823903369a4a9dab86116","name":"oh-package.json5","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\oh-package.json5","type":"file","isSymbolicLink":false,"fileMetaData":{"size":269,"lastModifiedTime":1695632211699}},{"hashValue":"94cde23849d24d7b4c50116f9d63d725","name":"ResourceTable.txt","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\ResourceTable.txt","type":"file","isSymbolicLink":false,"fileMetaData":{"size":27,"lastModifiedTime":1698044665018}},{"hashValue":"ae45559de2480bc70d782647539c87a9","name":"src","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d1732197995c7f8e834be72e56bec866","name":"main","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"f02f1982d32aa94a70d44596e261b365","name":"ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"9eda77fcd81df492830297a66f19de2b","name":"io","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a8b6bfcaad196674574a9a19f821f053","name":"flutter","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c3f2123de992ed2dbd349c42faa6bf94","name":"plugins","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"a73ddceefee53bd0ac6011fe311e4c5b","name":"pathprovider","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"3eba56cb57824fbfc070408312f41c09","name":"Messages.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\Messages.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":7545,"lastModifiedTime":1698027170940}},{"hashValue":"0ec1d5dd6a98d7b451807b34d6eaec32","name":"PathProviderPlugin.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\ets\\io\\flutter\\plugins\\pathprovider\\PathProviderPlugin.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":4706,"lastModifiedTime":1698027170931}}]}]}]}]}]},{"hashValue":"c7280466cd6cb30364af8cbdfe11f350","name":"module.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\module.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":406,"lastModifiedTime":1698044664828}},{"hashValue":"c8b0c1d9d5adf5ad1facbc15311568c7","name":"resources","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"base","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\base\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"en_US","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\en_US\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]},{"hashValue":"0e99451c368710b3fd660c4ce26f9f1a","name":"zh_CN","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"d6b3b638c405a120e2d4c2749281c244","name":"element","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"729a44cdc4bfe4a33860e45f85edc23d","name":"string.json","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\main\\resources\\zh_CN\\element\\string.json","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}}]}]}]}]},{"hashValue":"b07684f7777a2f703cac0fec56862a66","name":"test","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"c78a7b9e8f82f2213f5b0350ab7252e5","name":"List.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\List.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":108,"lastModifiedTime":1695632211699}},{"hashValue":"ec0cecaf2909eb7b848a158a2786add5","name":"LocalUnit.test.ets","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar\\src\\test\\LocalUnit.test.ets","type":"file","isSymbolicLink":false,"fileMetaData":{"size":1692,"lastModifiedTime":1695632211699}}]}]}]},"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default":{"hashValue":"876919e92069ce600cf972b0875777f7","name":"default","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default","type":"directory","isSymbolicLink":false,"children":[{"hashValue":"7505492774406aa9fff80dba7d7feac7","name":"path_provider.har","path":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default\\path_provider.har","type":"file","isSymbolicLink":false,"fileMetaData":{"size":3760,"lastModifiedTime":1698044665105}}]}} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json new file mode 100644 index 0000000000000000000000000000000000000000..c424f579e9642bd97516da860942f4f330a46bc7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/cache/task-cache.json @@ -0,0 +1 @@ +{":ohos:path_provider:default@PreBuild":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"apiType\",\"_value\":\"stageMode\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"codeType\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileApiVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"customTypes\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceType\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isSupportOhpmProj\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"profileModuleName\",\"_value\":\"path_provider\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"sdkToolchainsComponentVersion\",\"_value\":\"4.0.0.40\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetStatusCode\",\"_value\":2,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PreBuild","_key":":ohos:path_provider:default@PreBuild","_executionId":":ohos:path_provider:default@PreBuild:1698044664739","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"isDirectory":false,"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"isDirectory":false,"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\oh-package.json5",{"fileSnapShotHashValue":"c55207f83ac823903369a4a9dab86116"}]]},"_outputFiles":{"dataType":"Map","value":[]}},":ohos:path_provider:default@MergeProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"asanEnable\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"buildRoot\",\"_value\":\"build\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compatibleSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isDebug\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isHarModule\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"multiProjects\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"releaseType\",\"_value\":\"Release\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"targetSdkVersion\",\"_value\":10,\"_valueType\":\"number\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@MergeProfile","_key":":ohos:path_provider:default@MergeProfile","_executionId":":ohos:path_provider:default@MergeProfile:1698044664825","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\AppScope\\app.json5",{"fileSnapShotHashValue":"c5cbb5522de13fac82f033c7cd9b48d8"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\module.json5",{"fileSnapShotHashValue":"1b4eb7b03f613b971199abeae1d7ad6d"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]}},":ohos:path_provider:default@ProcessProfile":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"arkEnable\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"compileMode\",\"_value\":\"esmodule\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"deviceTypes\",\"_value\":[\"default\",\"tablet\"],\"_valueType\":\"object\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"dependency\",\"_value\":\"[]\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessProfile","_key":":ohos:path_provider:default@ProcessProfile","_executionId":":ohos:path_provider:default@ProcessProfile:1698044664829","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default\\module.json",{"fileSnapShotHashValue":"c7280466cd6cb30364af8cbdfe11f350"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}]]}},":ohos:path_provider:default@ProcessResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"resConfigJsonContent\",\"_value\":\"{\\\"configPath\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\process_profile\\\\\\\\default\\\\\\\\module.json\\\",\\\"packageName\\\":\\\"io.flutter.plugins.pathprovider\\\",\\\"output\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\",\\\"moduleNames\\\":\\\"path_provider\\\",\\\"ResourceTable\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\generated\\\\\\\\r\\\\\\\\default\\\\\\\\ResourceTable.h\\\"],\\\"moduleResources\\\":[\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\src\\\\\\\\main\\\\\\\\resources\\\"],\\\"dependencies\\\":[],\\\"ids\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\",\\\"definedIds\\\":\\\"D:\\\\\\\\project\\\\\\\\flutter-sig-package\\\\\\\\packages\\\\\\\\packages\\\\\\\\path_provider\\\\\\\\path_provider_ohos\\\\\\\\ohos\\\\\\\\path_provider\\\\\\\\build\\\\\\\\default\\\\\\\\intermediates\\\\\\\\res\\\\\\\\default\\\\\\\\ids_map\\\\\\\\id_defined.json\\\"}\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessResource","_key":":ohos:path_provider:default@ProcessResource","_executionId":":ohos:path_provider:default@ProcessResource:1697686151230","_inputFiles":{"dataType":"Map","value":[]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]}},":ohos:path_provider:default@ProcessLibs":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@ProcessLibs","_key":":ohos:path_provider:default@ProcessLibs","_executionId":":ohos:path_provider:default@ProcessLibs:1698044664930","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\libs",{"isDirectory":true,"fileSnapShotHashValue":"fb414dab48788ac59123df55cae63f0b"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}]]}},":ohos:path_provider:default@CompileResource":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"TARGET_CONFIG\",\"_value\":\"{\\\"name\\\":\\\"default\\\"}\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe,-l,D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\intermediates\\\\res\\\\default\\\\resConfig.json\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"D:\\\\tools\\\\devecostudio-windows-4.0.3.601\\\\devecostudio-windows-4.0.3.601\\\\sdk\\\\WinSDK\\\\openharmony\\\\10\\\\toolchains\\\\restool.exe\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@CompileResource","_key":":ohos:path_provider:default@CompileResource","_executionId":":ohos:path_provider:default@CompileResource:1698044664937","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources",{"fileSnapShotHashValue":"c8b0c1d9d5adf5ad1facbc15311568c7"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json",{"isDirectory":false,"fileSnapShotHashValue":"1c8e8a915a9b7f222d4cf94722d1bb42"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resConfig.json",{"isDirectory":false,"fileSnapShotHashValue":"d1d25a5d183601133bbabec3842873ac"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default",{"isDirectory":true,"fileSnapShotHashValue":"76f5c8d078ca69ae9175830aa99a05dc"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h",{"isDirectory":false,"fileSnapShotHashValue":"d021dd9a3167074553dba4f2c5854465"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default",{"isDirectory":true,"fileSnapShotHashValue":"93721c69ae9a43a6b6b026ce4ba28ad2"}]]}},":ohos:path_provider:default@PackageHar":{"_inputs":[{"dataType":"ValueEntry","value":"{\"_name\":\"hasNativeOption\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"needCppTypes\",\"_value\":false,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"harModuleJson\",\"_value\":\"D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar\\\\src\\\\main\\\\module.json5\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"isOhpmProject\",\"_value\":true,\"_valueType\":\"boolean\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"artifactType\",\"_value\":\"original\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_COMMAND\",\"_value\":\"C:\\\\Users\\\\z30010942\\\\nodejs\\\\npm.cmd,pack\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_TOOLCHAIN\",\"_value\":\"\",\"_valueType\":\"string\"}"},{"dataType":"ValueEntry","value":"{\"_name\":\"BUILTIN_TASK_ENV\",\"_value\":\"cwd:D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build\\\\default\\\\cache\\\\default\\\\default@PackageHar;\",\"_valueType\":\"string\"}"}],"_successful":true,"_projectName":"ohos","_moduleName":"path_provider","_taskName":"default@PackageHar","_key":":ohos:path_provider:default@PackageHar","_executionId":":ohos:path_provider:default@PackageHar:1698044665025","_inputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\merge_profile\\default",{"isDirectory":true,"fileSnapShotHashValue":"de5eea44e80e5ff634766ec94c928117"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider",{"isDirectory":true,"test":{"dataType":"RegExp","value":"^(?!D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\libs|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\build|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\node_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\oh_modules|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.cxx|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.previewer|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.hvigor|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.gitignore|D:\\\\project\\\\flutter-sig-package\\\\packages\\\\packages\\\\path_provider\\\\path_provider_ohos\\\\ohos\\\\path_provider\\\\.ohpmignore).*"},"fileSnapShotHashValue":"7190fb2c4d706ed6e0e4babda37414da"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\libs\\default",{"isDirectory":true,"fileSnapShotHashValue":""}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ResourceTable.txt",{"isDirectory":false,"fileSnapShotHashValue":"94cde23849d24d7b4c50116f9d63d725"}]]},"_outputFiles":{"dataType":"Map","value":[["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@PackageHar",{"isDirectory":true,"fileSnapShotHashValue":"77ec3ff3075d1e1b0f77eea3593fc54a"}],["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default",{"isDirectory":true,"fileSnapShotHashValue":"876919e92069ce600cf972b0875777f7"}]]}}} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json new file mode 100644 index 0000000000000000000000000000000000000000..e55e21ac77968038ea81d662bea7ef034aa7b14b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/logs/details/details.json @@ -0,0 +1,16 @@ +{ + "totalTime": 481506500, + "moduleNum": 1, + "taskTime": { + "compileArkTS": 0, + "buildArkTS": 0, + "compileJS": 0, + "buildJS": 0, + "compileResource": 0, + "packageHap": 0, + "signHap": 0 + }, + "isIncremental": true, + "hasIncremental": false, + "isParallel": true +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json new file mode 100644 index 0000000000000000000000000000000000000000..ca06e5bb15cfd13c1535a1a9f14d0141af5ebbf3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/outputs/sync/output.json @@ -0,0 +1,39 @@ +{ + "ohos-module-path_provider": { + "SELECT_TARGET": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build", + "TARGETS": { + "default": { + "SOURCE_ROOT": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main", + "RESOURCES_PATH": [ + "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources" + ], + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\outputs\\default", + "INTERMEDIA_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates", + "JS_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out\\default", + "JS_LITE_ASSETS_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader_out_lite\\default", + "RES_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default", + "RES_PROFILE_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\resources\\base\\profile", + "ETS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileArkTS\\esmodule", + "JS_SUPER_VISUAL_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\cache\\default\\default@CompileJS\\jsbundle", + "WORKER_LOADER": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\loader\\default\\loader.json", + "MANIFEST_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\manifest\\default", + "OUTPUT_METADATA_JSON": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\hap_metadata\\default\\output_metadata.json" + }, + "BUILD_OPTION": { + "debuggable": true + } + } + } + }, + "ohos-project": { + "SELECT_PRODUCT_NAME": "default", + "MODULE_BUILD_DIR": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build", + "BUNDLE_NAME": "io.flutter.plugins.pathprovider", + "BUILD_PATH": { + "OUTPUT_PATH": "C:\\Users\\hched\\Desktop\\path_provider_ohos\\ohos\\build\\outputs\\default" + } + }, + "version": 1 +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json new file mode 100644 index 0000000000000000000000000000000000000000..c812c2d046ee61ce12cbc028f21d33e82ac413a1 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/.hvigor/report/report.json @@ -0,0 +1,31 @@ +{ + "version": "1.0", + "workerIdList": [ + -1 + ], + "metrics": [ + { + "type": "build_line", + "endTime": 1699407048308, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "path_provider", + "workerId": -1, + "startTime": 1699407048307 + }, + { + "type": "build_line", + "endTime": 1699407048309, + "status": "closed", + "children": [], + "name": "overallTime", + "taskName": "init", + "taskPath": "ohos", + "workerId": -1, + "startTime": 1699407048309 + } + ], + "workLog": [] +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/app.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..68d6882c192e3684e2e9e50a05846b4839fff894 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/app.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..553ced4f7ebe2ed3fca66c4ef9637ce3ad65d12e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "path_provider" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/build-profile.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f32c5b25053f32d49b76722cb29cae05613d0e9b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/build-profile.json5 @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.cer", + "storePassword": "0000001A14E9D3E5C4DF2ED15CED1A37B72F435E8D176F43E415FF2213D4C9C753FA62E51E4621A952A5", + "keyAlias": "debugKey", + "keyPassword": "0000001AC6F51F5DA12538489C8E00F23C111099A8622DA17D8D6B2FE7A456D4D2D21C903D3DEB198EC9", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_io.flutter.plugins.pathprovider.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ], + "buildModeSet": [ + { + "name": "debug", + }, + { + "name": "release" + } + ] + }, + "modules": [ + { + "name": "path_provider", + "srcPath": "./path_provider" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2ffa0cb2249176e10a8fa9129c1b8b51748ccb72 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..7c7ca4943335f83f706349b541ff3b70e53a92e9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorfile.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..074db93779d1676b411a97eab2494a87d42e6f5a --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorfile.ts @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..ed562224b09a826aaa884251da665106dc5412c2 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw @@ -0,0 +1,62 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +#!/bin/bash + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw.bat b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..fec4ce9e55404e6b1d608ad93d5f7163299c7829 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/hvigorw.bat @@ -0,0 +1,78 @@ +# +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/local.properties b/ohos/test_octo_image/lib/path_provider_ohos/ohos/local.properties new file mode 100644 index 0000000000000000000000000000000000000000..864e8480e5edabc3faccd6c365441bf21a0d27da --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/local.properties @@ -0,0 +1,9 @@ +# This file is automatically generated by DevEco Studio. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file should *NOT* be checked into Version Control Systems, +# as it contains information specific to your local configuration. +# +# For customization when using a Version Control System, please read the header note. +nodejs.dir=C:/Users/hched/node/node-16.20.1 +hwsdk.dir=C:/Users/hched/AppData/Local/Huawei/Sdk \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8117ee588b7b4e9899feee78e294b5fbb14fbc3f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package-lock.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..34d7eb8b76b831719418a82841264ad20ba51466 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/oh-package.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2e04dee6c3a89e1a9d25df85a1d69d14f7b9bc63 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build-profile.json5 @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..989c850d90269886e5bbab58d829e9ba7257ebe1 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/build-profile.json5 @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..47e6e1f81d365872f101585f5dbf816bcad65864 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/hvigorfile.ts @@ -0,0 +1,2 @@ +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4f86ec5788fae9bfb7c37a62e1fe493278c81e19 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/oh-package.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "name": "path_provider", + "version": "1.0.0", + "description": "Please describe the basic information.", + "main": "index.ets", + "author": "", + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_ohos.har" + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..28597a654670bde1dfe147bd6033286fa8f4f7b4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,237 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..a654eef7ce1cf993c6dd7381b480aa5323ab4806 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,168 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..12ddf6a9a9e09489e6c97403e95cb9ae8acccd9d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b2dd4f1d969e706afc3a52f1b472ae099f65330 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/cache/default/default@PackageHar/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h new file mode 100644 index 0000000000000000000000000000000000000000..7804e730e1b4dbdb21b54729d5039a3f06d01347 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/generated/r/default/ResourceTable.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2023 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef RESOURCE_TABLE_H +#define RESOURCE_TABLE_H + +#include + +namespace OHOS { +const int32_t STRING_PAGE_SHOW = 0x01000000; +} +#endif \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..4f015a18d4e8ed4fbb0ffd3ce585624a2d3c8d31 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/merge_profile/default/module.json @@ -0,0 +1,21 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..5fe3850329df700867f0f4692936181c9dd1f6b9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/process_profile/default/module.json @@ -0,0 +1,24 @@ +{ + "app": { + "bundleName": "io.flutter.plugins.pathprovider", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ], + "virtualMachine": "ark9.0.0.0", + "compileMode": "esmodule", + "dependencies": [] + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..6f0f5b65f1dfdf0b3c0b8377b94b4031058d22a3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x01000000 \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json new file mode 100644 index 0000000000000000000000000000000000000000..384d0290daf29cee301a5271dec2824791a3d614 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/ids_map/id_defined.json @@ -0,0 +1,10 @@ +{ + "record" : + [ + { + "id" : "0x01000000", + "name" : "page_show", + "type" : "string" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json new file mode 100644 index 0000000000000000000000000000000000000000..fd826dbf47a8c5bd149d62909693a88a3df49a52 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/module.json @@ -0,0 +1,27 @@ +{ + "app" : + { + "apiReleaseType" : "Release", + "bundleName" : "io.flutter.plugins.pathprovider", + "compileSdkType" : "HarmonyOS", + "compileSdkVersion" : "4.0.0.40", + "debug" : true, + "minAPIVersion" : 40000010, + "targetAPIVersion" : 40000010, + "versionCode" : 1000000, + "versionName" : "1.0.0" + }, + "module" : + { + "compileMode" : "esmodule", + "dependencies" : [], + "deviceTypes" : + [ + "default", + "tablet" + ], + "name" : "path_provider", + "type" : "har", + "virtualMachine" : "ark9.0.0.0" + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json new file mode 100644 index 0000000000000000000000000000000000000000..272edbc65fdba3d0fd4ba496cc6c181d0aebc721 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resConfig.json @@ -0,0 +1 @@ +{"configPath":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\process_profile\\default\\module.json","packageName":"io.flutter.plugins.pathprovider","output":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default","moduleNames":"path_provider","ResourceTable":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\generated\\r\\default\\ResourceTable.h"],"moduleResources":["D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\src\\main\\resources"],"dependencies":[],"ids":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map","definedIds":"D:\\project\\flutter-sig-package\\packages\\packages\\path_provider\\path_provider_ohos\\ohos\\path_provider\\build\\default\\intermediates\\res\\default\\ids_map\\id_defined.json"} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index new file mode 100644 index 0000000000000000000000000000000000000000..3b7227cd2f2eb4b8f1ecc2cd52ad2411dd6f01d9 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/intermediates/res/default/resources.index differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..b49073ac77deb7ab1a4722ef4e4fb34a2bb57893 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/build/default/outputs/default/path_provider.har differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..d1a91468a73f05396b9e08abaabfe8717b73fbb4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/hvigorfile.ts @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..146d26c0fbde7fade1030172bc679b8f857a7490 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/libs/flutter_embedding.har differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c853354a5124d1a08452a3f20b6582244af1fed7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh-package.json5 @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +{ + "license": "Apache-2.0", + "devDependencies": { + "@ohos/flutter_ohos": "file:libs/flutter_embedding.har" + }, + "author": "", + "name": "path_provider", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159750ecea7bec636e067dea44f6b469601d685 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x02000000 \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..95e376706d75437dce67c79dfd886e97fa82f276 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/build-profile.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + } + ], +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c96b70703b57d3e53a171aabf07727db248e94b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/index.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export { FlutterAbility } from './src/main/ets/embedding/ohos/FlutterAbility' + +export { FlutterPage } from './src/main/ets/embedding/ohos/FlutterPage' diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..2aa191e0adafd258a3aee290e137f579d35ec427 Binary files /dev/null and b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c4acdada0ca16f1a1a4ada0bda0b669a04062911 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "Apache-2.0", + "devDependencies": { + "@types/libflutter.so": "file:./src/main/cpp/types/libflutter" + }, + "author": "", + "name": "flutter_embedding", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..bb628633cdb60882359286a05a10befeb05427fc --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts @@ -0,0 +1,66 @@ +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import image from '@ohos.multimedia.image'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; + +export const getContext: (a: number) => napiContext; + +export class napiContext { + onPageShow(); + + onPageHide(); +} + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => {}; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + +export const nativeAttach: (napi: FlutterNapi) => number; + +export const nativeRunBundleAndSnapshotFromLibrary: ( + nativeShellHolderId: number, + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +//Send a data-carrying response to a platform message received from Dart. +export const nativeInvokePlatformMessageResponseCallback: (nativeShellHolderId: number, responseId: number, message: ArrayBuffer, position: number) => void; + +// Send an empty response to a platform message received from Dart. +export const nativeInvokePlatformMessageEmptyResponseCallback: (nativeShellHolderId: number, responseId: number) => void; + +// Send a data-carrying platform message to Dart. +export const nativeDispatchPlatformMessage: (nativeShellHolderId: number, channel: String, message: ArrayBuffer, position: number, responseId: number) => void; + +// Send an empty platform message to Dart. +export const nativeDispatchEmptyPlatformMessage: (nativeShellHolderId: number, channel: String, responseId: number) => void; + +export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array) => void; + +export const nativeImageDecodeCallback: (width: number, height: number, imageGeneratorPointer: number, pixelMap : image.PixelMap) => void; + +export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..cb1b4f1eb7f1eaf5f362ec2c66d225dd5dc1c240 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts @@ -0,0 +1,252 @@ +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import image from '@ohos.multimedia.image'; + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => void; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + + +/** + * 加载dart工程构建产物 + */ +export const nativeRunBundleAndSnapshotFromLibrary: ( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +/** + * 初始化SkFontMgr::RefDefault(),skia引擎文字管理初始化 + */ +export const nativePrefetchDefaultFontManager: () => void; + +/** + * 返回是否支持软件绘制 + */ +export const nativeGetIsSoftwareRenderingEnabled: () => boolean; + +/** + * attach flutterNapi实例给到 native engine,这个支持rkts到flutter平台的无关引擎之间的通信。 + * attach只需要执行一次 + */ +export const nativeAttach: (flutterNapi: FlutterNapi) => number; + +/** + * 从当前的flutterNapi复制一个新的实例 + */ +export const nativeSpawn: ( + nativeSpawningShellId: number, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + initialRoute: string, + entrypointArgs: Array +) => FlutterNapi; + +/** + * Detaches flutterNapi和engine之间的关联 + * 这个方法执行前提是flutterNapi已经和engine关联 + */ +export const nativeDestroy: ( + nativeShellHolderId: number +) => void; + +// 不需要实现,未使用到 +// export const nativeImageHeaderCallback: ( +// imageGeneratorPointer: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceCreated: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceWindowChanged: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceChanged: ( +// nativeShellHolderId: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceDestroyed: ( +// nativeShellHolderId: number +// ) => void; + +/** + * 把物理屏幕参数通知到native + */ +export const nativeSetViewportMetrics: ( + nativeShellHolderId: number, + devicePixelRatio: number, + physicalWidth: number, + physicalHeight: number, + physicalPaddingTop: number, + physicalPaddingRight: number, + physicalPaddingBottom: number, + physicalPaddingLeft: number, + physicalViewInsetTop: number, + physicalViewInsetRight: number, + physicalViewInsetBottom: number, + physicalViewInsetLeft: number, + systemGestureInsetTop: number, + systemGestureInsetRight: number, + systemGestureInsetBottom: number, + systemGestureInsetLeft: number, + physicalTouchSlop: number, + displayFeaturesBounds: Array, + displayFeaturesType: Array, + displayFeaturesState: Array +) => void; + +/** + * 设置能力参数 + */ +export const nativeSetAccessibilityFeatures: ( + nativeShellHolderId: number, + flags: number +) => void; + +/** + * 清除某个messageData + */ +export const nativeCleanupMessageData: ( + messageData: number +) => void; + +/** + * 发送一个空的PlatformMessage + */ +export const nativeDispatchEmptyPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + responseId: number +) => void; + +/** + * 发送一个PlatformMessage + */ +export const nativeDispatchPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + message: ArrayBuffer, + position: number, + responseId: number +) => void; + +/** + * 空的PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageEmptyResponseCallback: ( + nativeShellHolderId: number, + responseId: number +) => void; + +/** + * PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageResponseCallback: ( + nativeShellHolderId: number, + responseId: number, + message: ArrayBuffer, + position: number +) => void; + + +/** + * load一个合法的.so文件到dart vm + */ +export const nativeLoadDartDeferredLibrary: ( + nativeShellHolderId: number, + loadingUnitId: number, + searchPaths: Array +) => void; + +/** + * 设置ResourceManager和assetBundlePath到engine + */ +export const nativeUpdateOhosAssetManager: ( + nativeShellHolderId: number, + resourceManager: resourceManager.ResourceManager, + assetBundlePath: string +) => void; + +/** + * 加载动态库,或者dart库失败时的通知 + */ +export const nativeDeferredComponentInstallFailure: ( + loadingUnitId: number, + error: string, + isTransient: boolean +) => void; + +/** + * 从engine获取当前绘制pixelMap + */ +export const nativeGetPixelMap: () => image.PixelMap; + +/** + * 应用低内存警告 + */ +export const nativeNotifyLowMemoryWarning: ( + nativeShellHolderId: number +) => void; + +// ----- Start FlutterTextUtils Methods ---- +/** + * 下面的方法,从键盘输入中判断当前字符是否是emoji,实现优先级低 + */ +export const nativeFlutterTextUtilsIsEmoji: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifier: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifierBase: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsVariationSelector: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsRegionalIndicator: ( + codePoint: number +) => boolean; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..0e11cf2c3c8aefb7ddcff477d21b2894d08b5520 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 @@ -0,0 +1,6 @@ +{ + "name": "libflutter.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6f2f8b0e5dd765611d87ac3b2c2c552ff5adb2 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from './embedding/engine/FlutterNapi'; +import FlutterLoader from './embedding/engine/loader/FlutterLoader'; + +/** + * flutter相关主要类的单例持有,帮助实现自身和其他类的实例化管理 + */ +export default class FlutterInjector { + private static instance: FlutterInjector; + + private flutterLoader: FlutterLoader; + private flutterNapi: FlutterNapi; + + static getInstance(): FlutterInjector { + if (FlutterInjector.instance == null) { + FlutterInjector.instance = new FlutterInjector(); + } + return FlutterInjector.instance; + } + /** + * 初始化 + */ + private constructor() { + this.flutterNapi = new FlutterNapi(); + this.flutterLoader = new FlutterLoader(this.flutterNapi); + } + + getFlutterLoader(): FlutterLoader { + return this.flutterLoader; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..77c89858b09535ee4b34af516b7eb18cb5d5a3ee --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets @@ -0,0 +1,34 @@ +import FlutterView from '../embedding/ohos/FlutterView'; +import common from '@ohos.app.ability.common'; +import PlatformViewController from '../plugin/platform/PlatformViewsController' +import Log from '../util/Log'; + +export default class FlutterPluginRegistry { + private mPlatformViewsController: PlatformViewController; + private mFlutterView: FlutterView; + private mContext: common.Context; + + constructor() { + this.mPlatformViewsController = new PlatformViewController(); + } + + attach(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mContext = context; + } + + detach(): void { + this.mPlatformViewsController.detach(); + this.mPlatformViewsController.onDetachedFromNapi(); + this.mFlutterView = null; + this.mContext = null; + } + + destroy(): void { + this.mPlatformViewsController.onDetachedFromNapi(); + } + + onPreEngineRestart(): void{ + this.mPlatformViewsController.onPreEngineRestart(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..07497e672b21c51727c1a45166504e19603e4063 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * 基础component,还未封装,看情况是否使用 + */ +@Component +export default struct FlutterComponent { + build() { + Row() { + Column() { + Text("xxx") + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a16a419d9c7a5df84379278cdc7fb113624d7f7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets @@ -0,0 +1,277 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LifecycleChannel from './systemchannels/LifecycleChannel'; +import DartExecutor, { DartEntrypoint } from './dart/DartExecutor'; +import FlutterShellArgs from './FlutterShellArgs'; +import FlutterInjector from '../../FlutterInjector'; +import FlutterLoader from './loader/FlutterLoader'; +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from './FlutterNapi'; +import NavigationChannel from './systemchannels/NavigationChannel'; +import Log from '../../util/Log'; +import TestChannel from './systemchannels/TestChannel' +import FlutterEngineConnectionRegistry from './FlutterEngineConnectionRegistry'; +import PluginRegistry from './plugins/PluginRegistry'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import TextInputChannel from './systemchannels/TextInputChannel'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import PlatformChannel from './systemchannels/PlatformChannel'; +import FlutterEngineGroup from './FlutterEngineGroup'; +import SystemChannel from './systemchannels/SystemChannel'; +import MouseCursorChannel from './systemchannels/MouseCursorChannel'; +import RestorationChannel from './systemchannels/RestorationChannel'; +import LocalizationChannel from './systemchannels/LocalizationChannel'; +import AccessibilityChannel from './systemchannels/AccessibilityChannel'; +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' +import SettingsChannel from './systemchannels/SettingsChannel'; +import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; + +const TAG = "FlutterEngine"; + +/** + * 操作FlutterEngin相关 + */ +export default class FlutterEngine implements EngineLifecycleListener{ + private engineLifecycleListeners = new Set(); + + dartExecutor: DartExecutor; + private flutterLoader: FlutterLoader; + private assetManager: resourceManager.ResourceManager; + //channel定义 + private lifecycleChannel: LifecycleChannel; + private navigationChannel: NavigationChannel; + private textInputChannel: TextInputChannel; + private testChannel: TestChannel; + private platformChannel: PlatformChannel; + private systemChannel: SystemChannel; + private mouseCursorChannel: MouseCursorChannel; + private restorationChannel: RestorationChannel; + + private accessibilityChannel: AccessibilityChannel; + private localeChannel: LocalizationChannel; + private flutterNapi: FlutterNapi; + private pluginRegistry: FlutterEngineConnectionRegistry; + private textInputPlugin: TextInputPlugin; + private localizationPlugin: LocalizationPlugin; + private settingsChannel: SettingsChannel; + private platformViewsController: PlatformViewsController; + + /** + * 需要初始化的工作: + * 1、初始化DartExecutor + * 2、初始化所有channel + * 3、初始化plugin + * 4、初始化flutterLoader + * 5、初始化flutterNapi + * 6、engineLifecycleListeners + */ + constructor(context: common.Context, flutterLoader: FlutterLoader, flutterNapi: FlutterNapi, platformViewsController: PlatformViewsController) { + const injector: FlutterInjector = FlutterInjector.getInstance(); + + if(flutterNapi == null){ + flutterNapi = FlutterInjector.getInstance().getFlutterNapi(); + } + this.flutterNapi = flutterNapi; + this.assetManager = context.resourceManager; + + this.dartExecutor = new DartExecutor(this.flutterNapi, this.assetManager); + this.dartExecutor.onAttachedToNAPI(); + + if(flutterLoader == null){ + flutterLoader = injector.getFlutterLoader(); + } + this.flutterLoader = flutterLoader; + + if(platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + this.platformViewsController = platformViewsController; + this.platformViewsController.attach(context, null, this.dartExecutor); + } + + async init(context: common.Context, dartVmArgs: Array, automaticallyRegisterPlugins: boolean, + waitForRestorationData: boolean, group: FlutterEngineGroup) { + if (!this.flutterNapi.isAttached()) { + await this.flutterLoader.startInitialization(context) + this.flutterLoader.ensureInitializationComplete(dartVmArgs); + } + //channel初始化 + this.lifecycleChannel = new LifecycleChannel(this.dartExecutor); + this.navigationChannel = new NavigationChannel(this.dartExecutor); + this.textInputChannel = new TextInputChannel(this.dartExecutor); + this.testChannel = new TestChannel(this.dartExecutor); + this.platformChannel = new PlatformChannel(this.dartExecutor); + this.systemChannel = new SystemChannel(this.dartExecutor); + this.mouseCursorChannel = new MouseCursorChannel(this.dartExecutor); + this.restorationChannel = new RestorationChannel(this.dartExecutor, waitForRestorationData); + this.settingsChannel = new SettingsChannel(this.dartExecutor); + + this.localeChannel = new LocalizationChannel(this.dartExecutor); + this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); + this.flutterNapi.addEngineLifecycleListener(this); + this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); + + // It should typically be a fresh, unattached NAPI. But on a spawned engine, the NAPI instance + // is already attached to a native shell. In that case, the Java FlutterEngine is created around + // an existing shell. + if (!this.flutterNapi.isAttached()) { + this.attachToNapi(); + } + + this.pluginRegistry = new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, this.flutterLoader, group); + this.localizationPlugin.sendLocaleToFlutter(); + } + + private attachToNapi(): void { + Log.d(TAG, "Attaching to NAPI."); + this.flutterNapi.attachToNative(); + + if (!this.isAttachedToNapi()) { + throw new Error("FlutterEngine failed to attach to its native Object reference."); + } + this.flutterNapi.setLocalizationPlugin(this.localizationPlugin); + } + + async spawn(context: common.Context, + dartEntrypoint: DartEntrypoint, + initialRoute: string, + dartEntrypointArgs: Array, + platformViewsController: PlatformViewsController, + automaticallyRegisterPlugins: boolean, waitForRestorationData: boolean) { + if (!this.isAttachedToNapi()) { + throw new Error( + "Spawn can only be called on a fully constructed FlutterEngine"); + } + + const newFlutterNapi = + this.flutterNapi.spawn( + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + initialRoute, + dartEntrypointArgs); + const flutterEngine = new FlutterEngine( + context, + null, + newFlutterNapi, + platformViewsController + ); + await flutterEngine.init(context, null, automaticallyRegisterPlugins, waitForRestorationData, null) + return flutterEngine + } + + private isAttachedToNapi(): boolean { + return this.flutterNapi.isAttached(); + } + + getLifecycleChannel(): LifecycleChannel { + return this.lifecycleChannel; + } + + getNavigationChannel(): NavigationChannel { + return this.navigationChannel; + } + + getTextInputChannel(): TextInputChannel { + return this.textInputChannel; + } + + getPlatformChannel(): PlatformChannel { + return this.platformChannel; + } + + getSystemChannel(): SystemChannel { + return this.systemChannel; + } + + getLocaleChannel(): LocalizationChannel { + return this.localeChannel; + } + + getMouseCursorChannel(): MouseCursorChannel { + return this.mouseCursorChannel; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor + } + + getPlugins(): PluginRegistry { + return this.pluginRegistry; + } + + getAbilityControlSurface(): AbilityControlSurface { + return this.pluginRegistry; + } + + getSettingsChannel() { + return this.settingsChannel; + } + + onPreEngineRestart(): void { + + } + + onEngineWillDestroy(): void { + + } + + addEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(listener); + } + + removeEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.delete(listener); + } + + destroy(): void { + Log.d(TAG, "Destroying."); + this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) + this.flutterNapi.removeEngineLifecycleListener(this); + this.pluginRegistry.detachFromAbility(); + this.platformViewsController.onDetachedFromNapi(); + } + + getRestorationChannel(): RestorationChannel{ + return this.restorationChannel; + } + + getAccessibilityChannel(): AccessibilityChannel { + return this.accessibilityChannel; + } + + getLocalizationPlugin(): LocalizationPlugin { + return this.localizationPlugin; + } + + getSystemLanguages(): void { + return this.flutterNapi.getSystemLanguages(); + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } +} + +export interface EngineLifecycleListener { + onPreEngineRestart(): void; + + onEngineWillDestroy(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..78db31cae3a9d154a09f9f85541115dc4452573f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from "./FlutterEngine" + +export default class FlutterEngineCache { + private static instance : FlutterEngineCache; + private cachedEngines: Map = new Map(); + + static getInstance(): FlutterEngineCache { + if (FlutterEngineCache.instance == null) { + FlutterEngineCache.instance = new FlutterEngineCache(); + } + return FlutterEngineCache.instance; + } + /** + * 返回engineId对应的FlutterEngine是否存在 + */ + contains(engineId: String) : boolean { + return this.cachedEngines.has(engineId); + } + + /** + * 返回engineId对应的FlutterEngine + */ + get(engineId: String) : FlutterEngine { + return this.cachedEngines.get(engineId); + } + /** + * 将传入的FlutterEngine与engineId放在缓存中 + */ + put(engineId :String, engine: FlutterEngine): void { + if(engine != null) { + this.cachedEngines.set(engineId, engine); + } else { + this.cachedEngines.delete(engineId); + } + } + /** + * 移除engineId对应的FlutterEngine + */ + remove(engineId: String) : void { + this.put(engineId, null); + } + + /** + * 移除cachedEngines所有中所有的FlutterEngine + */ + clear():void { + this.cachedEngines.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..7709ea8a31e98f794314a7e2f3b84e890f1eee9f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PluginRegistry from './plugins/PluginRegistry'; +import { FlutterAssets, FlutterPlugin, FlutterPluginBinding } from './plugins/FlutterPlugin'; +import FlutterEngine from './FlutterEngine'; +import AbilityAware from './plugins/ability/AbilityAware'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import { + AbilityPluginBinding, + WindowFocusChangedListener, + OnSaveStateListener, + NewWantListener +} from './plugins/ability/AbilityPluginBinding'; +import HashSet from '@ohos.util.HashSet'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import common from '@ohos.app.ability.common'; +import FlutterLoader from './loader/FlutterLoader'; +import Log from '../../util/Log'; +import ToolUtils from '../../util/ToolUtils'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import ExclusiveAppComponent from '../ohos/ExclusiveAppComponent'; +import FlutterEngineGroup from './FlutterEngineGroup'; + +const TAG = "FlutterEngineCxnRegstry"; + +export default class FlutterEngineConnectionRegistry implements PluginRegistry, AbilityControlSurface { + // PluginRegistry + private plugins = new Map(); + + // Standard FlutterPlugin + private flutterEngine: FlutterEngine; + private pluginBinding: FlutterPluginBinding; + + // AbilityAware + private abilityAwarePlugins = new Map(); + + private exclusiveAbility: ExclusiveAppComponent; + private abilityPluginBinding: FlutterEngineAbilityPluginBinding; + + constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader, group: FlutterEngineGroup) { + this.flutterEngine = flutterEngine; + this.pluginBinding = new FlutterPluginBinding(appContext, this.flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), group, this.flutterEngine.getPlatformViewsController()?.getRegistry()); + } + + add(plugin: FlutterPlugin): void { + try { + if (this.has(plugin.getUniqueClassName())) { + Log.w( + TAG, + "Attempted to register plugin (" + + plugin + + ") but it was " + + "already registered with this FlutterEngine (" + + this.flutterEngine + + ")."); + return; + } + + Log.w(TAG, "Adding plugin: " + plugin); + // Add the plugin to our generic set of plugins and notify the plugin + // that is has been attached to an engine. + this.plugins.set(plugin.getUniqueClassName(), plugin); + plugin.onAttachedToEngine(this.pluginBinding); + + // For AbilityAware plugins, add the plugin to our set of AbilityAware + // plugins, and if this engine is currently attached to an Ability, + // notify the AbilityAware plugin that it is now attached to an Ability. + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + const abilityAware: ESObject = plugin; + this.abilityAwarePlugins.set(plugin.getUniqueClassName(), abilityAware); + if (this.isAttachedToAbility()) { + abilityAware.onAttachedToAbility(this.abilityPluginBinding); + } + } + } finally { + + } + } + + addList(plugins: Set): void { + plugins.forEach(plugin => this.add(plugin)) + } + + has(pluginClassName: string): boolean { + return this.plugins.has(pluginClassName); + } + + get(pluginClassName: string): FlutterPlugin { + return this.plugins.get(pluginClassName); + } + + remove(pluginClassName: string): void { + const plugin = this.plugins.get(pluginClassName); + if (plugin == null) { + return; + } + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + if (this.isAttachedToAbility()) { + const abilityAware: ESObject = plugin; + abilityAware.onDetachedFromAbility(); + } + this.abilityAwarePlugins.delete(pluginClassName); + } + // Notify the plugin that is now detached from this engine. Then remove + // it from our set of generic plugins. + plugin.onDetachedFromEngine(this.pluginBinding); + this.plugins.delete(pluginClassName) + } + + removeList(pluginClassNames: Set): void { + pluginClassNames.forEach(plugin => this.remove(plugin)) + } + + removeAll(): void { + this.removeList(new Set(this.plugins.keys())); + this.plugins.clear(); + } + + private isAttachedToAbility(): boolean { + return this.exclusiveAbility != null; + } + + attachToAbility(exclusiveAbility: ExclusiveAppComponent): void { + if (this.exclusiveAbility != null) { + this.exclusiveAbility.detachFromFlutterEngine(); + } + // If we were already attached to an app component, detach from it. + this.detachFromAppComponent(); + this.exclusiveAbility = exclusiveAbility; + this.attachToAbilityInternal(exclusiveAbility.getAppComponent(),); + } + + detachFromAbility(): void { + if (this.isAttachedToAbility()) { + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onDetachedFromAbility()) + this.detachFromAbilityInternal(); + } else { + Log.e(TAG, "Attempted to detach plugins from an Ability when no Ability was attached."); + } + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.abilityPluginBinding.onNewWant(want, launchParams); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.abilityPluginBinding.onWindowFocusChanged(hasFocus); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + return this.abilityPluginBinding.onSaveState(reason, wantParam); + } + + private detachFromAppComponent(): void { + if (this.isAttachedToAbility()) { + this.detachFromAbility(); + } + } + + private attachToAbilityInternal(ability: UIAbility): void { + this.abilityPluginBinding = new FlutterEngineAbilityPluginBinding(ability); + // Notify all AbilityAware plugins that they are now attached to a new Ability. + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onAttachedToAbility(this.abilityPluginBinding)); + } + + private detachFromAbilityInternal(): void { + this.exclusiveAbility = null; + this.abilityPluginBinding = null; + } + + destroy(): void{ + this.detachFromAppComponent(); + // Remove all registered plugins. + this.removeAll(); + } +} + +class FlutterEngineAbilityPluginBinding implements AbilityPluginBinding { + private ability: UIAbility; + private onNewWantListeners = new HashSet(); + private onWindowFocusChangedListeners = new HashSet(); + private onSaveStateListeners = new HashSet(); + + constructor(ability: UIAbility) { + this.ability = ability; + + } + + getAbility(): UIAbility { + return this.ability; + } + + addOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.add(listener) + } + + removeOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.remove(listener) + } + + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.add(listener) + } + + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.remove(listener) + } + + addOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.add(listener) + } + + removeOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.remove(listener) + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.onNewWantListeners.forEach((listener, key) => { + listener.onNewWant(want, launchParams) + }); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.onWindowFocusChangedListeners.forEach((listener, key) => { + listener.onWindowFocusChanged(hasFocus) + }); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + this.onSaveStateListeners.forEach((listener, key) => { + listener.onSaveState(reason, wantParam) + }); + return AbilityConstant.OnSaveResult.ALL_AGREE; + } +} + +class DefaultFlutterAssets implements FlutterAssets { + private flutterLoader: FlutterLoader; + + constructor(flutterLoader: FlutterLoader) { + this.flutterLoader = flutterLoader; + } + + getAssetFilePathByName(assetFileName: string, packageName?: string): string { + return this.flutterLoader.getLookupKeyForAsset(assetFileName, packageName); + } + + getAssetFilePathBySubpath(assetSubpath: string, packageName?: string) { + return this.flutterLoader.getLookupKeyForAsset(assetSubpath, packageName); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets new file mode 100644 index 0000000000000000000000000000000000000000..05e35aec1b7b6f50ab8df336bdd69fbbe21febc8 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" +import common from '@ohos.app.ability.common' +import FlutterLoader from './loader/FlutterLoader' +import FlutterInjector from '../../FlutterInjector' +import { DartEntrypoint } from './dart/DartExecutor' +import PlatformViewsController from '../../plugin/platform/PlatformViewsController' +import ArrayList from '@ohos.util.ArrayList' + +export default class FlutterEngineGroup { + private activeEngines: ArrayList = new ArrayList(); + + constructor() { + + } + + async checkLoader(context: common.Context, args: Array) { + let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!loader.initialized) { + await loader.startInitialization(context.getApplicationContext()); + loader.ensureInitializationComplete(args); + } + } + + async createAndRunEngineByOptions(options: Options) { + let engine: FlutterEngine = null; + let context: common.Context = options.getContext(); + let dartEntrypoint: DartEntrypoint = options.getDartEntrypoint(); + let initialRoute: string = options.getInitialRoute(); + let dartEntrypointArgs: Array = options.getDartEntrypointArgs(); + let platformViewsController: PlatformViewsController = options.getPlatformViewsController(); + let automaticallyRegisterPlugins: boolean = options.getAutomaticallyRegisterPlugins(); + let waitForRestorationData: boolean = options.getWaitForRestorationData(); + + if (dartEntrypoint == null) { + dartEntrypoint = DartEntrypoint.createDefault(); + } + + if (platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + + if (this.activeEngines.length == 0) { + engine = this.createEngine(context, platformViewsController); + await engine.init(context, null, // String[]. The Dart VM has already started, this arguments will have no effect. + automaticallyRegisterPlugins, // boolean. + waitForRestorationData, // boolean. + this) + if (initialRoute != null) { + engine.getNavigationChannel().setInitialRoute(initialRoute); + } + } else { + engine = await this.activeEngines[0] + .spawn( + context, + dartEntrypoint, + initialRoute, + dartEntrypointArgs, + platformViewsController, + automaticallyRegisterPlugins, + waitForRestorationData); + } + this.activeEngines.add(engine); + + const engineToCleanUpOnDestroy = engine; + let listener: EngineLifecycleListener = new EngineLifecycleListenerImpl( + platformViewsController, + this.activeEngines, + engineToCleanUpOnDestroy); + engine.addEngineLifecycleListener(listener); + return engine; + } + + createEngine(context: common.Context, platformViewsController: PlatformViewsController): FlutterEngine { + return new FlutterEngine(context, null, null, platformViewsController); + } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private platformViewsController: PlatformViewsController; + private activeEngines: ArrayList = new ArrayList(); + private engine: FlutterEngine; + + constructor( + platformViewsController: PlatformViewsController, + activeEngines: ArrayList, + engine: FlutterEngine) { + this.platformViewsController = platformViewsController; + this.activeEngines = activeEngines; + this.engine = engine; + } + onPreEngineRestart(): void { + this.platformViewsController.onPreEngineRestart(); + } + onEngineWillDestroy(): void { + this.activeEngines.remove(this.engine); + } +} + +export class Options { + private context: common.Context; + private dartEntrypoint: DartEntrypoint; + private initialRoute: string; + private dartEntrypointArgs: Array; + private platformViewsController: PlatformViewsController; + private automaticallyRegisterPlugins: boolean = true; + private waitForRestorationData: boolean = false; + + constructor(context: common.Context) { + this.context = context; + } + + getContext(): common.Context { + return this.context; + } + + getDartEntrypoint(): DartEntrypoint { + return this.dartEntrypoint; + } + + getInitialRoute(): string { + return this.initialRoute; + } + + getDartEntrypointArgs(): Array { + return this.dartEntrypointArgs; + } + + getAutomaticallyRegisterPlugins(): boolean { + return this.automaticallyRegisterPlugins; + } + + getWaitForRestorationData(): boolean { + return this.waitForRestorationData; + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } + + setDartEntrypoint(dartEntrypoint: DartEntrypoint): Options { + this.dartEntrypoint = dartEntrypoint; + return this; + } + + setInitialRoute(initialRoute: string): Options { + this.initialRoute = initialRoute; + return this; + } + + setDartEntrypointArgs(dartEntrypointArgs: Array): Options { + this.dartEntrypointArgs = dartEntrypointArgs; + return this; + } + + setAutomaticallyRegisterPlugins(automaticallyRegisterPlugins: boolean): Options { + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + return this; + } + + setWaitForRestorationData(waitForRestorationData: boolean): Options { + this.waitForRestorationData = waitForRestorationData; + return this; + } + + setPlatformViewsController(platformViewsController: PlatformViewsController): Options { + this.platformViewsController = platformViewsController; + return this; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b251069ce950ee8a0fb3d2f08b723a2d1e6f78 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngineGroup from './FlutterEngineGroup'; + +export default class FlutterEngineGroupCache { + static readonly instance = new FlutterEngineGroupCache(); + + private cachedEngineGroups = new Map(); + + contains(engineGroupId: string): boolean { + return this.cachedEngineGroups.has(engineGroupId); + } + + get(engineGroupId: string): FlutterEngineGroup { + return this.cachedEngineGroups.get(engineGroupId); + } + + put(engineGroupId: string, engineGroup?: FlutterEngineGroup) { + if (engineGroup != null) { + this.cachedEngineGroups.set(engineGroupId, engineGroup); + } else { + this.cachedEngineGroups.delete(engineGroupId); + } + } + + clear(): void { + this.cachedEngineGroups.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets new file mode 100644 index 0000000000000000000000000000000000000000..902699e44c585b355df699b78cca69b58f021055 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import flutter from 'libflutter.so'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log'; +import resourceManager from '@ohos.resourceManager'; +import { PlatformMessageHandler } from './dart/PlatformMessageHandler'; +import { FlutterCallbackInformation } from '../../view/FlutterCallbackInformation'; +import image from '@ohos.multimedia.image'; +import { EngineLifecycleListener } from './FlutterEngine'; +import { ByteBuffer } from '../../util/ByteBuffer'; +import { Action } from '../../view/AccessibilityBridge' +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin'; +import i18n from '@ohos.i18n'; + +const TAG = "FlutterNapi"; + +enum ContextType { + APP_LIFECYCLE = 0, + JS_PAGE_LIFECYCLE, +} + +/** + * 提供arkTs的flutterNAPI接口 + */ +export default class FlutterNapi { + hasInit: boolean = false; + //是否已实现 + hasImplemented: boolean = false; + + nativeShellHolderId: number = null; + platformMessageHandler: PlatformMessageHandler; + private engineLifecycleListeners = new Set(); + accessibilityDelegate: AccessibilityDelegate; + localizationPlugin: LocalizationPlugin; + + /** + * 更新刷新率 + * @param rate + */ + updateRefreshRate(refreshRateFPS : number) { + flutter.nativeUpdateRefreshRate(refreshRateFPS); + } + + init(context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number) { + if (this.hasInit) { + throw Error("the engine has init"); + } + this.hasInit = true; + Log.w(TAG, "init: bundlePath=" + bundlePath + " appStoragePath=" + appStoragePath + " engineCachesPath=" + engineCachesPath + " args=" + JSON.stringify(args)); + flutter.nativeInit(context, args, bundlePath, appStoragePath, engineCachesPath, initTimeMillis); + } + + attachToNative(): void { + this.nativeShellHolderId = flutter.nativeAttach(this); + Log.w(TAG, "nativeShellHolderId=" + this.nativeShellHolderId); + } + + runBundleAndSnapshotFromLibrary( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array) { + Log.w(TAG, "init: bundlePath=" + bundlePath + " entrypointFunctionName=" + entrypointFunctionName + " pathToEntrypointFunction=" + pathToEntrypointFunction + " entrypointArgs=" + JSON.stringify(entrypointArgs)) + flutter.nativeRunBundleAndSnapshotFromLibrary(this.nativeShellHolderId, bundlePath, entrypointFunctionName, pathToEntrypointFunction, assetManager, entrypointArgs); + }; + + /** + * 当前so方法是否都实现 + * @returns + */ + checkImplemented(methodName: string = ""): boolean { + if (!this.hasImplemented) { + Log.e(TAG, "this method has not implemented -> " + methodName) + } + return this.hasImplemented; + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.ensureRunningOnMainThread(); + this.platformMessageHandler = platformMessageHandler; + } + + private ensureAttachedToNative(): void { + if (this.nativeShellHolderId == null) { + throw new Error( + "Cannot execute operation because FlutterNapi is not attached to native."); + } + } + + private nativeNotifyLowMemoryWarning(nativeShellHolderId: number): void { + + } + + static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation { + return null; + } + + notifyLowMemoryWarning(): void { + this.ensureRunningOnMainThread(); + this.ensureAttachedToNative(); + this.nativeNotifyLowMemoryWarning(this.nativeShellHolderId); + } + + isAttached(): boolean { + return this.nativeShellHolderId != null; + } + + private ensureRunningOnMainThread(): void { + + } + + dispatchEmptyPlatformMessage(channel: String, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + flutter.nativeDispatchEmptyPlatformMessage(this.nativeShellHolderId, channel, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + /** Sends a reply {@code message} from Android to Flutter over the given {@code channel}. */ + dispatchPlatformMessage(channel: String, message: ArrayBuffer, position: number, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + + const uintArrayBuff = new Uint8Array(message) + let text = '' + for (let i = 0; i < uintArrayBuff.byteLength; i++) { + text += uintArrayBuff[i] + ',' + } + Log.w(TAG, "message=" + message.byteLength + ",text=" + text); + flutter.nativeDispatchPlatformMessage(this.nativeShellHolderId, channel, message, position, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + invokePlatformMessageEmptyResponseCallback(responseId: number): void { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageEmptyResponseCallback(this.nativeShellHolderId, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + invokePlatformMessageResponseCallback(responseId: number, message: ArrayBuffer, position: number) { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageResponseCallback( + this.nativeShellHolderId, responseId, message, position); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setViewportMetrics(devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array): void { + if (this.isAttached()) { + flutter.nativeSetViewportMetrics(this.nativeShellHolderId, devicePixelRatio, + physicalWidth, + physicalHeight, + physicalPaddingTop, + physicalPaddingRight, + physicalPaddingBottom, + physicalPaddingLeft, + physicalViewInsetTop, + physicalViewInsetRight, + physicalViewInsetBottom, + physicalViewInsetLeft, + systemGestureInsetTop, + systemGestureInsetRight, + systemGestureInsetBottom, + systemGestureInsetLeft, + physicalTouchSlop, + displayFeaturesBounds, + displayFeaturesType, + displayFeaturesState); + } + } + + spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array): FlutterNapi { + return new FlutterNapi(); + } + + addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(engineLifecycleListener); + } + + removeEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener) { + this.engineLifecycleListeners.delete(engineLifecycleListener); + } + + //Called by native to respond to a platform message that we sent. + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.w(TAG, "called handlePlatformMessageResponse Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handlePlatformMessageResponse(replyId, reply); + } + } + + // Called by native on any thread. + handlePlatformMessage(channel: string, message: ArrayBuffer, replyId: number, messageData: number): void { + Log.w(TAG, "called handlePlatformMessage Channel: " + channel + ". Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handleMessageFromDart(channel, message, replyId, messageData); + } + } + + // Called by native to notify first Flutter frame rendered. + onFirstFrame(): void { + Log.d(TAG, "called onFirstFrame") + } + + // Called by native. + onPreEngineRestart(): void { + Log.d(TAG, "called onPreEngineRestart") + this.engineLifecycleListeners.forEach( listener => listener.onPreEngineRestart()); + } + + // /** Invoked by native to obtain the results of OHOS's locale resolution algorithm. */ + computePlatformResolvedLocale(strings: Array): Array { + Log.d(TAG, "called computePlatformResolvedLocale " + JSON.stringify(strings)) + return [] + } + + decodeImage(buffer: ArrayBuffer, imageGeneratorAddress: number): void { + Log.d(TAG, "called decodeImage=" + buffer.byteLength) + const imageSourceApi = image.createImageSource(buffer); + let tempPixelMap: image.PixelMap = null; + imageSourceApi.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }).then(pixelMap => { + Log.d(TAG, "called createPixelMap end " + pixelMap.getPixelBytesNumber()) + tempPixelMap = pixelMap + return pixelMap.getImageInfo() + }).then(imageInfo => { + Log.d(TAG, `nativeImageHeaderCallback width=${imageInfo.size.width} height=${imageInfo.size.height} imageGeneratorAddress=${imageGeneratorAddress}`) + flutter.nativeImageDecodeCallback(imageInfo.size.width, imageInfo.size.height, imageGeneratorAddress, tempPixelMap) + }).catch((error: ESObject) => { + Log.d(TAG, "decodeImage error=" + JSON.stringify(error)) + flutter.nativeImageDecodeCallback(0, 0, imageGeneratorAddress, null); + }) + } + + setSemanticsEnabled(enabled: boolean, responseId: number): void { + if (this.isAttached()) { + this.nativeSetSemanticsEnabled(enabled); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + // Send an empty response to a platform message received from Dart. + nativeSetSemanticsEnabled(enabled: boolean):void {} + + setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { + if (this.isAttached()) { + this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeSetAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void {} + + dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { + if (this.isAttached()) { + this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeDispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void {} + + setAccessibilityDelegate(delegate: AccessibilityDelegate, responseId: number): void { + if (this.isAttached()) { + this.accessibilityDelegate = delegate; + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setLocalizationPlugin(localizationPlugin: LocalizationPlugin): void { + this.localizationPlugin = localizationPlugin; + } + + /** + * 获取系统语言列表 + * @param rate + */ + getSystemLanguages() { + Log.d(TAG, "called getSystemLanguages ") + let index: number; + let systemLanguages = i18n.System.getPreferredLanguageList(); + for (index = 0; index < systemLanguages.length; index++) { + Log.d(TAG, "systemlanguages "+ index + ":" + systemLanguages[index]); + } + flutter.nativeGetSystemLanguages(this.nativeShellHolderId, systemLanguages); + } +} + +export interface AccessibilityDelegate { + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void; + + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d63d83de313f52eba3f8fa6d2ed584f7bee44bd --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterOverlaySurface { + + private id: number; + + constructor(id: number) { + this.id = id + } + + getId(): number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a3cd75a49b7c53742072aa30541204060fc82e6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Want from '@ohos.app.ability.Want'; + +/** + * 封装flutter shell的参数 + */ +export default class FlutterShellArgs { + static ARG_KEY_TRACE_STARTUP = "trace-startup"; + static ARG_TRACE_STARTUP = "--trace-startup"; + static ARG_KEY_START_PAUSED = "start-paused"; + static ARG_START_PAUSED = "--start-paused"; + static ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; + static ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; + static ARG_KEY_ENDLESS_TRACE_BUFFER = "endless-trace-buffer"; + static ARG_ENDLESS_TRACE_BUFFER = "--endless-trace-buffer"; + static ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; + static ARG_USE_TEST_FONTS = "--use-test-fonts"; + static ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; + static ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; + static ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; + static ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; + static ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; + static ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; + static ARG_KEY_TRACE_SKIA = "trace-skia"; + static ARG_TRACE_SKIA = "--trace-skia"; + static ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; + static ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; + static ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; + static ARG_TRACE_SYSTRACE = "--trace-systrace"; + static ARG_KEY_ENABLE_IMPELLER = "enable-impeller"; + static ARG_ENABLE_IMPELLER = "--enable-impeller"; + static ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "dump-skp-on-shader-compilation"; + static ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "--dump-skp-on-shader-compilation"; + static ARG_KEY_CACHE_SKSL = "cache-sksl"; + static ARG_CACHE_SKSL = "--cache-sksl"; + static ARG_KEY_PURGE_PERSISTENT_CACHE = "purge-persistent-cache"; + static ARG_PURGE_PERSISTENT_CACHE = "--purge-persistent-cache"; + static ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; + static ARG_VERBOSE_LOGGING = "--verbose-logging"; + static ARG_KEY_OBSERVATORY_PORT = "observatory-port"; + static ARG_OBSERVATORY_PORT = "--observatory-port="; + static ARG_KEY_DART_FLAGS = "dart-flags"; + static ARG_DART_FLAGS = "--dart-flags"; + static ARG_KEY_MSAA_SAMPLES = "msaa-samples"; + static ARG_MSAA_SAMPLES = "--msaa-samples"; + + /** + * 从意图中解析参数,创建shellArgs + * @returns + */ + static fromWant(want: Want): FlutterShellArgs { + //tdo 解析want + return new FlutterShellArgs(); + } + + //参数 + args: Set = new Set(); + + add(arg: string) { + this.args.add(arg); + } + + remove(arg: string) { + this.args.delete(arg); + } + + toArray(): Array { + return Array.from(this.args); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ecfc7d5ef46c57923679789eb82f86eb83ef77 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default interface ExclusiveAppComponent { + /** + * Called when another App Component is about to become attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} this App Component is currently attached to. + * + *

This App Component's connections to the {@link io.flutter.embedding.engine.FlutterEngine} + * are still valid at the moment of this call. + */ + detachFromFlutterEngine(): void; + + /** + * Retrieve the App Component behind this exclusive App Component. + * + * @return The app component. + */ + getAppComponent(): T; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..07a374a7109e9a1ffcd5680220534c9796681e64 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -0,0 +1,414 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import window from '@ohos.window'; +import { FlutterAbilityDelegate, Host } from './FlutterAbilityDelegate'; +import Log from '../../util/Log'; +import FlutterEngine from '../engine/FlutterEngine'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import common from '@ohos.app.ability.common'; +import Want from '@ohos.app.ability.Want'; +import display from '@ohos.display'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import { AsyncCallback } from '@ohos.base'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import I18n from '@ohos.i18n' +import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; +import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; +import { DVModelContainer } from '../../view/DynamicView/dynamicView'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { Configuration } from '@ohos.app.ability.Configuration'; + +const TAG = "FlutterAbility"; +/** + * flutter ohos基础ability,请在让主ability继承自该类。 + * 该类主要职责: + * 1、持有FlutterAbilityDelegate并初始化; + * 2、生命周期传递; + */ +export class FlutterAbility extends UIAbility implements Host { + private delegate: FlutterAbilityDelegate; + private windowStage: window.WindowStage; + private mainWindow: window.Window; + private viewportMetrics = new ViewportMetrics(); + private displayInfo: display.Display; + + /** + * onCreate + * 1、create and attach delegate + * 2、config windows transparent noNeed? + * 3、lifecycle.onCreate + * 4. setContentView() noNeed + */ + async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + Log.i(TAG, "bundleCodeDir=" + this.context.bundleCodeDir); + // globalThis.flutterAbility = this + this.displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = this.displayInfo.densityPixels + + this.delegate = new FlutterAbilityDelegate(this); + await this.delegate.onAttach(this.context); + Log.i(TAG, 'onAttach end'); + this.delegate.platformPlugin.setUIAbilityContext(this.context); + this.delegate.onRestoreInstanceState(want); + this.delegate.sendSettings(); + + if (this.stillAttachedForEvent("onCreate")) { + this.delegate.onCreate(); + } + + console.log('MyAbility onCreate'); + // globalThis.applicationContext = this.context.getApplicationContext(); + } + + onDestroy() { + if (this.stillAttachedForEvent("onDestroy")) { + this.delegate.onDestroy(); + } + } + + /** + * window状态改变回调 + * @param windowStage + */ + async onWindowStageCreate(windowStage: window.WindowStage) { + this.windowStage = windowStage + try { + windowStage.on('windowStageEvent', (data) => { + let stageEventType: window.WindowStageEventType = data; + switch (stageEventType) { + case window.WindowStageEventType.SHOWN: // 切到前台 + Log.i(TAG, 'windowStage foreground.'); + break; + case window.WindowStageEventType.ACTIVE: // 获焦状态 + Log.i(TAG, 'windowStage active.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(true); + } + break; + case window.WindowStageEventType.INACTIVE: // 失焦状态 + Log.i(TAG, 'windowStage inactive.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(false); + } + break; + case window.WindowStageEventType.HIDDEN: // 切到后台 + Log.i(TAG, 'windowStage background.'); + break; + default: + break; + } + }); + + this.mainWindow = windowStage.getMainWindowSync() + this.mainWindow.on('windowSizeChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('avoidAreaChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('keyboardHeightChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.loadContent(); + this.mainWindow.setWindowLayoutFullScreen(true); + } catch (exception) { + Log.e(TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception)); + } + } + + loadContent() { + if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { + Log.i(TAG, 'loadContent'); + this.windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Log.e(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + this.onWindowPropertiesUpdated(); + Log.i(TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + if (this.stillAttachedForEvent("onWindowStageCreate")) { + this.delegate.onWindowStageCreate(); + } + this.delegate.getFlutterNapi().updateRefreshRate(this.displayInfo.refreshRate) + this.onFlutterEngineReady() + } + } + + onFlutterEngineReady(): void { + + } + + private updateViewportMetrics() { + this.delegate.getFlutterNapi().setViewportMetrics(this.viewportMetrics.devicePixelRatio, + this.viewportMetrics.physicalWidth, + this.viewportMetrics.physicalHeight, + this.viewportMetrics.physicalViewPaddingTop, + this.viewportMetrics.physicalViewPaddingRight, + this.viewportMetrics.physicalViewPaddingBottom, + this.viewportMetrics.physicalViewPaddingLeft, + this.viewportMetrics.physicalViewInsetTop, + this.viewportMetrics.physicalViewInsetRight, + this.viewportMetrics.physicalViewInsetBottom, + this.viewportMetrics.physicalViewInsetLeft, + this.viewportMetrics.systemGestureInsetTop, + this.viewportMetrics.systemGestureInsetRight, + this.viewportMetrics.systemGestureInsetBottom, + this.viewportMetrics.systemGestureInsetLeft, + this.viewportMetrics.physicalTouchSlop, + new Array(0), + new Array(0), + new Array(0)) + } + + onWindowStageDestroy() { + if (this.stillAttachedForEvent("onWindowStageDestroy")) { + this.delegate.onWindowStageDestroy(); + } + } + + onForeground() { + if (this.stillAttachedForEvent("onForeground")) { + this.delegate.onForeground(); + } + } + + onBackground() { + if (this.stillAttachedForEvent("onBackground")) { + this.delegate.onBackground(); + } + } + + release() { + if (this.delegate != null) { + this.delegate.release(); + this.delegate = null; + } + } + + /** + * host所有实现方法开始======start + */ + + getAbility(): UIAbility { + return this; + } + + shouldDispatchAppLifecycleState(): boolean { + return true; + } + + provideFlutterEngine(context: common.Context): FlutterEngine { + return null; + } + + configureFlutterEngine(flutterEngine: FlutterEngine) { + + } + + cleanUpFlutterEngine(flutterEngine: FlutterEngine) { + + } + + getFlutterShellArgs(): FlutterShellArgs { + return FlutterShellArgs.fromWant(this.getWant()); + } + + getDartEntrypointArgs(): Array { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; + } + return new Array() + } + + detachFromFlutterEngine() { + if (this.delegate != null) { + this.delegate.onDetach(); + } + } + + popSystemNavigator(): boolean { + return false; + } + + shouldAttachEngineToActivity(): boolean { + return true; + } + + getDartEntrypointLibraryUri(): string { + return null; + } + + getAppBundlePath(): string { + return null; + } + + getDartEntrypointFunctionName(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; + } + return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT + } + + getInitialRoute(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string; + } + return null + } + + getWant(): Want { + return this.launchWant; + } + + shouldDestroyEngineWithHost(): boolean { + return true; + } + + shouldRestoreAndSaveState(): boolean{ + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; + } + if (this.getCachedEngineId() != null) { + // Prevent overwriting the existing state in a cached engine with restoration state. + return false; + } + return true; + } + + getCachedEngineId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string + } + + getCachedEngineGroupId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string + } + + /** + * host所有实现方法结束======end + */ + private stillAttachedForEvent(event: string) { + Log.i(TAG, 'Ability ' + event); + if (this.delegate == null) { + Log.w(TAG, "FlutterAbility " + event + " call after release."); + return false; + } + if (!this.delegate.isAttached) { + Log.w(TAG, "FlutterAbility " + event + " call after detach."); + return false; + } + return true; + } + + addPlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.addPlugin(plugin) + } + } + + removePlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.removePlugin(plugin) + } + } + + private onWindowPropertiesUpdated(){ + if (!this.delegate.isAttached) { + return; + } + let systemAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let gestureAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + let keyboardAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + const properties = this.mainWindow.getWindowProperties(); + this.viewportMetrics.physicalWidth = properties.windowRect.width; + this.viewportMetrics.physicalHeight = properties.windowRect.height; + + this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea.topRect.height + this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea.leftRect.width + this.viewportMetrics.physicalViewPaddingBottom = systemAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea.rightRect.width + + this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea.topRect.height + this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea.leftRect.width + this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea.rightRect.width + + this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea.topRect.height + this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea.leftRect.width + this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea.bottomRect.height + this.viewportMetrics.systemGestureInsetRight = gestureAvoidArea.rightRect.width + + this.updateViewportMetrics() + } + + onMemoryLevel(level: AbilityConstant.MemoryLevel): void { + Log.i(TAG, 'onMemoryLevel: ' + level); + if (level === AbilityConstant.MemoryLevel.MEMORY_LEVEL_CRITICAL) { + this.delegate.onLowMemory(); + } + } + + onConfigurationUpdated(config: Configuration){ + Log.i(TAG, 'onConfigurationUpdated config:' + JSON.stringify(config)); + this.delegate.flutterEngine.getSettingsChannel().startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK + ? PlatformBrightness.LIGHT : PlatformBrightness.DARK); + } + + getWindowId(callback: AsyncCallback): void { + if (callback === null) { + return; + } + try { + window.getLastWindow(this.context, (error, win) => { + if (error.code) { + callback(error, -1); + return; + } + let windowId = win.getWindowProperties().id; + callback(error, windowId); + }); + } catch (err) { + Log.e(TAG, "get window id error!"); + callback(err, -1); + } + } +} + +export class ViewportMetrics { + devicePixelRatio: number = 1.0; + physicalWidth: number = 0; + physicalHeight: number = 0; + physicalViewPaddingTop: number = 0; + physicalViewPaddingRight: number = 0; + physicalViewPaddingBottom: number = 0; + physicalViewPaddingLeft: number = 0; + physicalViewInsetTop: number = 0; + physicalViewInsetRight: number = 0; + physicalViewInsetBottom: number = 0; + physicalViewInsetLeft: number = 0; + systemGestureInsetTop: number = 0; + systemGestureInsetRight: number = 0; + systemGestureInsetBottom: number = 0; + systemGestureInsetLeft: number = 0; + physicalTouchSlop = -1; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9046981a47219a7eb553dd4d3baeefa639069281 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import FlutterEngineConfigurator from './FlutterEngineConfigurator'; +import FlutterEngineProvider from './FlutterEngineProvider'; +import FlutterEngine from '../engine/FlutterEngine'; +import PlatformPlugin, { PlatformPluginDelegate } from '../../plugin/PlatformPlugin'; +import Want from '@ohos.app.ability.Want'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import DartExecutor, { DartEntrypoint } from '../engine/dart/DartExecutor'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import Log from '../../util/Log'; +import FlutterInjector from '../../FlutterInjector'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from './ExclusiveAppComponent'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import FlutterEngineCache from '../engine/FlutterEngineCache'; +import FlutterEngineGroupCache from '../engine/FlutterEngineGroupCache'; +import FlutterEngineGroup, { Options } from '../engine/FlutterEngineGroup'; +import MouseCursorPlugin, { MouseCursorViewDelegate } from '../../plugin/mouse/MouseCursorPlugin'; +import Settings from './Settings'; + +const TAG = "FlutterAbilityDelegate"; +const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; +const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; + +/** + * 主要职责: + * 1、初始化engine + * 2、处理ability生命周期回调 + */ +class FlutterAbilityDelegate implements ExclusiveAppComponent { + private host: Host; + flutterEngine: FlutterEngine; + platformPlugin: PlatformPlugin; + private context: common.Context; + private textInputPlugin: TextInputPlugin; + private isFlutterEngineFromHost: boolean; + private engineGroup: FlutterEngineGroup; + private mouseCursorPlugin: MouseCursorPlugin; + private settings: Settings; + + constructor(host: Host) { + this.host = host; + } + + /** + * 是否还attach在ability上 + */ + isAttached = false; + + async onAttach(context: common.Context): Promise { + this.context = context; + this.ensureAlive(); + if (this.flutterEngine == null) { + await this.setupFlutterEngine(); + } + //shouldAttachEngineToActivity + if (this.host.shouldAttachEngineToActivity()) { + // Notify any plugins that are currently attached to our FlutterEngine that they + // are now attached to an Ability. + Log.d(TAG, "Attaching FlutterEngine to the Ability that owns this delegate."); + this.flutterEngine.getAbilityControlSurface().attachToAbility(this); + } + + //providePlatformPlugin + + //configureFlutterEngine + this.isAttached = true; + Log.d(TAG, "onAttach end start loadcontent") + this.host.loadContent() + this.textInputPlugin = new TextInputPlugin(this.flutterEngine.getTextInputChannel()); + this.platformPlugin = new PlatformPlugin(this.flutterEngine.getPlatformChannel(), this.context); + this.mouseCursorPlugin = new MouseCursorPlugin(this.host, this.flutterEngine.getMouseCursorChannel()); + this.settings = new Settings(this.flutterEngine.getSettingsChannel()); + this.flutterEngine.getSystemLanguages(); + } + + /** + * 加载app.so资源或者snapshot + */ + private doInitialFlutterViewRun(): void { + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + const libraryUri = this.host.getDartEntrypointLibraryUri(); + Log.d(TAG, "Executing Dart entrypoint: " + this.host.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); + + // The engine needs to receive the Flutter app's initial route before executing any + // Dart code to ensure that the initial route arrives in time to be applied. + this.flutterEngine.getNavigationChannel().setInitialRoute(initialRoute); + + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride == '') { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint: DartEntrypoint = new DartEntrypoint( + appBundlePathOverride, + this.host.getDartEntrypointLibraryUri(), + this.host.getDartEntrypointFunctionName() + ); + this.flutterEngine.dartExecutor.executeDartEntrypoint(dartEntrypoint, this.host.getDartEntrypointArgs()); + } + + private maybeGetInitialRouteFromIntent(want: Want): string { + return null; + } + + + /** + * 通过参数,配置flutterEngine + * @param want + */ + onRestoreInstanceState(want: Want) { + let frameworkState: Uint8Array = want.parameters[FRAMEWORK_RESTORATION_BUNDLE_KEY] as Uint8Array; + if (this.host.shouldRestoreAndSaveState()) { + this.flutterEngine.getRestorationChannel().setRestorationData(frameworkState ?? null); + } + } + + /** + * 初始化flutterEngine + */ + async setupFlutterEngine() { + // First, check if the host wants to use a cached FlutterEngine. + const cachedEngineId = this.host.getCachedEngineId(); + Log.d(TAG, "cachedEngineId=" + cachedEngineId); + if (cachedEngineId && cachedEngineId.length > 0) { + this.flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); + this.isFlutterEngineFromHost = true; + if (this.flutterEngine == null) { + throw new Error( + "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" + + cachedEngineId + + "'"); + } + return; + } + + // Second, defer to subclasses for a custom FlutterEngine. + this.flutterEngine = this.host.provideFlutterEngine(this.context); + if (this.flutterEngine != null) { + this.isFlutterEngineFromHost = true; + return; + } + + // Third, check if the host wants to use a cached FlutterEngineGroup + // and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine + const cachedEngineGroupId = this.host.getCachedEngineGroupId(); + Log.d(TAG, "cachedEngineGroupId=" + cachedEngineGroupId); + if (cachedEngineGroupId != null) { + const flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); + if (flutterEngineGroup == null) { + throw new Error( + "The requested cached FlutterEngineGroup did not exist in the FlutterEngineGroupCache: '" + + cachedEngineGroupId + + "'"); + } + + this.flutterEngine = await flutterEngineGroup.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context))); + this.isFlutterEngineFromHost = false; + return; + } + + // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our + // FlutterView. + Log.d( + TAG, + "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); + + let group = this.engineGroup; + if (group == null) { + group = new FlutterEngineGroup(); + await group.checkLoader(this.context, this.host.getFlutterShellArgs().toArray()); + } + this.flutterEngine = await group.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context) + .setAutomaticallyRegisterPlugins(false).setWaitForRestorationData(this.host.shouldRestoreAndSaveState()))); + this.isFlutterEngineFromHost = false; + } + + addEntrypointOptions(options: Options): Options { + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride.length == 0) { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint = new DartEntrypoint(appBundlePathOverride, null, this.host.getDartEntrypointFunctionName()); + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + return options + .setDartEntrypoint(dartEntrypoint) + .setInitialRoute(initialRoute) + .setDartEntrypointArgs(this.host.getDartEntrypointArgs()); + } + + /** + * 释放所有持有对象 + */ + release() { + this.host = null; + this.flutterEngine = null; + } + + onDetach() { + if (this.host.shouldAttachEngineToActivity()) { + // Notify plugins that they are no longer attached to an Activity. + Log.d(TAG, "Detaching FlutterEngine from the Ability"); + this.flutterEngine.getAbilityControlSurface().detachFromAbility(); + } + } + + onLowMemory(): void { + this.getFlutterNapi().notifyLowMemoryWarning(); + this.flutterEngine.getSystemChannel().sendMemoryPressureWarning(); + } + + /** + * 生命周期回调 + */ + + onCreate() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsInactive(); + } + } + + onDestroy() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsDetached(); + } + this.textInputPlugin.detach(); + } + + onWindowStageCreate() { + this.ensureAlive(); + this.doInitialFlutterViewRun(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onWindowStageDestroy() { + + } + + onWindowFocusChanged(hasFocus: boolean):void { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getAbilityControlSurface().onWindowFocusChanged(hasFocus); + if (hasFocus) { + this.flutterEngine.getLifecycleChannel().aWindowIsFocused(); + } else { + this.flutterEngine.getLifecycleChannel().noWindowsAreFocused(); + } + } + } + + onForeground() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onBackground() { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsPaused(); + } + } + + /** + * 生命周期回调结束 + */ + + shouldDispatchAppLifecycleState(): boolean { + return this.host.shouldDispatchAppLifecycleState() && this.isAttached; + } + + ensureAlive() { + if (this.host == null) { + throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); + } + } + + getFlutterNapi() { + return this.flutterEngine.getFlutterNapi() + } + + detachFromFlutterEngine() { + if (this.host.shouldDestroyEngineWithHost()) { + // The host owns the engine and should never have its engine taken by another exclusive + // activity. + throw new Error( + "The internal FlutterEngine created by " + + this.host + + " has been attached to by another activity. To persist a FlutterEngine beyond the " + + "ownership of this ablity, explicitly create a FlutterEngine"); + } + + // Default, but customizable, behavior is for the host to call {@link #onDetach} + // deterministically as to not mix more events during the lifecycle of the next exclusive + // activity. + this.host.detachFromFlutterEngine(); + } + + getAppComponent(): UIAbility { + const ability = this.host.getAbility(); + if (ability == null) { + throw new Error( + "FlutterActivityAndFragmentDelegate's getAppComponent should only " + + "be queried after onAttach, when the host's ability should always be non-null"); + } + return ability; + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.ensureAlive() + if (this.flutterEngine != null) { + Log.i(TAG, "Forwarding onNewWant() to FlutterEngine and sending pushRouteInformation message."); + this.flutterEngine.getAbilityControlSurface().onNewWant(want, launchParams); + const initialRoute = this.maybeGetInitialRouteFromIntent(want); + if (initialRoute && initialRoute.length > 0) { + this.flutterEngine.getNavigationChannel().pushRouteInformation(initialRoute); + } + } else { + Log.w(TAG, "onNewIntent() invoked before FlutterFragment was attached to an Activity."); + } + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); + this.ensureAlive(); + if (this.host.shouldRestoreAndSaveState()) { + wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] = this.flutterEngine.getRestorationChannel().getRestorationData(); + } + if (this.host.shouldAttachEngineToActivity()) { + const plugins:Record = {} + const result = this.flutterEngine.getAbilityControlSurface().onSaveState(reason, plugins); + wantParam[PLUGINS_RESTORATION_BUNDLE_KEY] = plugins; + return result + } + return AbilityConstant.OnSaveResult.ALL_REJECT + } + + addPlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().add(plugin) + } + + removePlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().remove(plugin.getUniqueClassName()) + } + + sendSettings(): void { + this.settings.sendSettings() + } +} + + +/** + * FlutterAbility句柄 + */ +interface Host extends FlutterEngineProvider, FlutterEngineConfigurator, PlatformPluginDelegate, MouseCursorViewDelegate { + + getAbility(): UIAbility; + + loadContent():void; + + shouldDispatchAppLifecycleState(): boolean; + + detachFromFlutterEngine(); + + shouldAttachEngineToActivity(): boolean; + + getCachedEngineId(): string; + + getCachedEngineGroupId(): string; + + /** + * Returns true if the {@link io.flutter.embedding.engine.FlutterEngine} used in this delegate + * should be destroyed when the host/delegate are destroyed. + */ + shouldDestroyEngineWithHost(): boolean; + + /** Returns the {@link FlutterShellArgs} that should be used when initializing Flutter. */ + getFlutterShellArgs(): FlutterShellArgs; + + /** Returns arguments that passed as a list of string to Dart's entrypoint function. */ + getDartEntrypointArgs(): Array; + + /** + * Returns the URI of the Dart library which contains the entrypoint method (example + * "package:foo_package/main.dart"). If null, this will default to the same library as the + * `main()` function in the Dart program. + */ + getDartEntrypointLibraryUri(): string; + + /** Returns the path to the app bundle where the Dart code exists. */ + getAppBundlePath(): string; + + /** + * Returns the Dart entrypoint that should run when a new {@link + * io.flutter.embedding.engine.FlutterEngine} is created. + */ + getDartEntrypointFunctionName(): string; + + /** Returns the initial route that Flutter renders. */ + getInitialRoute(): string; + + getWant(): Want; + + shouldRestoreAndSaveState(): boolean; +} + +export { Host, FlutterAbilityDelegate } \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets new file mode 100644 index 0000000000000000000000000000000000000000..996f455b9d045411425025f5c68089aee3f8938c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** The mode of the background of a Flutter {@code Activity}, either opaque or transparent. */ +enum BackgroundMode { + /** Indicates a FlutterActivity with an opaque background. This is the default. */ + opaque, + /** Indicates a FlutterActivity with a transparent background. */ + transparent +} + +export default class FlutterAbilityLaunchConfigs { + + static DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint"; + static DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri"; + static INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute"; + static SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; + static NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; + static HANDLE_DEEPLINKING_META_DATA_KEY = "flutter_deeplinking_enabled"; + // Intent extra arguments. + static EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; + static EXTRA_INITIAL_ROUTE = "route"; + static EXTRA_BACKGROUND_MODE = "background_mode"; + static EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; + static EXTRA_DART_ENTRYPOINT_ARGS = "dart_entrypoint_args"; + static EXTRA_CACHED_ENGINE_GROUP_ID = "cached_engine_group_id"; + static EXTRA_DESTROY_ENGINE_WITH_ACTIVITY = "destroy_engine_with_activity"; + static EXTRA_ENABLE_STATE_RESTORATION = "enable_state_restoration"; + + // Default configuration. + static DEFAULT_DART_ENTRYPOINT = "main"; + static DEFAULT_INITIAL_ROUTE = "/"; + static DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets new file mode 100644 index 0000000000000000000000000000000000000000..7953cad0836a9be4bf6bfd940594fdc787f45d66 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; + +export default interface FlutterEngineConfigurator { + + configureFlutterEngine(flutterEngine: FlutterEngine); + + cleanUpFlutterEngine(flutterEngine: FlutterEngine); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bdd7b6a809a77510f8942e81e0d91e7b4970893 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; +import common from '@ohos.app.ability.common'; + +export default interface FlutterEngineProvider { + provideFlutterEngine(context: common.Context): FlutterEngine; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..05695111937b486f3f498e9c87c12bdb85d829c5 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { PlatformViewWrapper } from '../../plugin/platform/PlatformViewWrapper'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { DVModel, + DVModelChildren, + DVModelContainer, + DVModelEvents, + DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +/** + * 基础page组件,承载XComponent组件 + */ +@Component +export struct FlutterPage { + @State message: string = 'Hello World'; + + @State rootDvModel: DVModelContainer = RootDvModeManager.getRootDvMode(); + + build() { + DynamicView({ + model: this.rootDvModel.model as DVModel, + params: this.rootDvModel.model.params as DVModelParameters, + events: this.rootDvModel.model.events as DVModelEvents, + children: this.rootDvModel.model.children as DVModelChildren, + customBuilder: this.rootDvModel.model.builder as ($$: Record<"params",DVModelParameters >) => void + //customBuilder: this.rootDvModel.model.builder as ($$: { params: DVModelParameters }) => void + }) + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets new file mode 100644 index 0000000000000000000000000000000000000000..083b148b1b3677895fe467c8f3fd0365bbd07cc2 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets @@ -0,0 +1,43 @@ +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; + +export default class OhosTouchProcessor { + private static POINTER_DATA_FIELD_COUNT: number = 35; + + static BYTES_PER_FIELD: number = 8; + + private static POINTER_DATA_FLAG_BATCHED: number = 1; + + public onTouchEvent(event: TouchEvent, transformMatrix: ESObject): void { + + } +} + +export enum PointerChange { + CANCEL = 0, + ADD = 1, + REMOVE = 2, + HOVER = 3, + DOWN = 4, + MOVE = 5, + UP = 6, + PAN_ZOOM_START = 7, + PAN_ZOOM_UPDATE = 8, + PAN_ZOOM_END = 9 +} + +export enum PointerDeviceKind { + TOUCH = 0, + MOUSE = 1, + STYLUS = 2, + INVERTED_STYLUS = 3, + TRACKPAD = 4, + UNKNOWN = 5 +} + +export enum PointerSignalKind { + NONE = 0, + SCROLL = 1, + SCROLL_INERTIA_CANCEL = 2, + SCALE = 3, + UNKNOWN = 4 +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets new file mode 100644 index 0000000000000000000000000000000000000000..a435d2a45cc960a5d6a4eb49c3d131c83b4d2dcb --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import SettingsChannel, { PlatformBrightness } from '../engine/systemchannels/SettingsChannel' +import I18n from '@ohos.i18n' + +export default class Settings { + settingsChannel: SettingsChannel; + + constructor(settingsChannel: SettingsChannel) { + this.settingsChannel = settingsChannel; + } + + sendSettings(): void { + this.settingsChannel.startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setTextScaleFactor(1.0) + .setNativeSpellCheckServiceDefined(false) + .setBrieflyShowPassword(false) + .setPlatformBrightness(PlatformBrightness.LIGHT) + .send(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets new file mode 100644 index 0000000000000000000000000000000000000000..9d4306f92610e0cf610e87e76dc051151d40f9ec --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets @@ -0,0 +1,73 @@ +/** Tracks the motion events received by the FlutterView. */ +import PlainArray from '@ohos.util.PlainArray'; +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; +import Queue from '@ohos.util.Queue'; + +export class TouchEventTracker { + private eventById : PlainArray; + private unusedEvents : Queue; + private static INSTANCE:TouchEventTracker; + + public static getInstance(): TouchEventTracker { + if (TouchEventTracker.INSTANCE == null) { + TouchEventTracker.INSTANCE = new TouchEventTracker(); + } + return TouchEventTracker.INSTANCE; + } + + constructor() { + this.eventById = new PlainArray(); + this.unusedEvents = new Queue(); + } + + /** Tracks the event and returns a unique MotionEventId identifying the event. */ + public track(event :TouchEvent) : TouchEventId { + const eventId:TouchEventId = TouchEventId.createUnique(); + this.eventById.add(eventId.getId(), event); + this.unusedEvents.add(eventId.getId()); + return eventId; + } + + /** + * Returns the MotionEvent corresponding to the eventId while discarding all the motion events + * that occurred prior to the event represented by the eventId. Returns null if this event was + * popped or discarded. + */ + public pop(eventId : TouchEventId) : TouchEvent { + // remove all the older events. + while (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() < eventId.getId()) { + this.eventById.remove(this.unusedEvents.pop()); + } + + // remove the current event from the heap if it exists. + if (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() == eventId.getId()) { + this.unusedEvents.pop(); + } + + const event : TouchEvent = this.eventById.get(eventId.getId()); + this.eventById.remove(eventId.getId()); + return event; + } +} + +/** Represents a unique identifier corresponding to a motion event. */ +export class TouchEventId { + private static ID_COUNTER : number = 0; + private id : number; + + constructor(id : number) { + this.id = id; + } + + public static from(id : number) : TouchEventId { + return new TouchEventId(id); + } + + public static createUnique() : TouchEventId { + return new TouchEventId(TouchEventId.ID_COUNTER++); + } + + public getId() : number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..fd5b302da20485bea675770c746ad93dd71e848d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets @@ -0,0 +1,8 @@ +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class WindowInfoRepositoryCallbackAdapterWrapper { + + constructor() { + } + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..9910f14b6d71e2fc70e55eb8c7846ccbeffa0180 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import PlatformChannel, { + AppSwitcherDescription, + Brightness, + ClipboardContentFormat, + HapticFeedbackType, + PlatformMessageHandler, + SoundType, + SystemChromeStyle, + SystemUiMode, + SystemUiOverlay +} from '../embedding/engine/systemchannels/PlatformChannel'; +import pasteboard from '@ohos.pasteboard'; +import Log from '../util/Log'; +import vibrator from '@ohos.vibrator'; +import window from '@ohos.window'; +import common from '@ohos.app.ability.common'; + +/** + * ohos实现platform plugin + */ +export default class PlatformPlugin { + private static TAG = "PlatformPlugin"; + private callback = new PlatformPluginCallback(); + + constructor(platformChannel: PlatformChannel, context: common.Context, platformPluginDelegate?: PlatformPluginDelegate) { + this.callback.platformChannel = platformChannel; + this.callback.context = context; + this.callback.applicationContext = context.getApplicationContext(); + this.callback.platform = this; + + try { + window.getLastWindow(context, (err, data) => { + if (err.code) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + return; + } + this.callback.windowClass = data; + }); + } catch (err) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + } + this.callback.platformPluginDelegate = platformPluginDelegate; + this.callback.platformChannel.setPlatformMessageHandler(this.callback); + } + + + updateSystemUiOverlays(): void { + this.callback.windowClass.setWindowSystemBarEnable(this.callback.showBarOrNavigation); + if (this.callback.currentTheme != null) { + this.callback.setSystemChromeSystemUIOverlayStyle(this.callback.currentTheme); + } + } + + setUIAbilityContext(context: common.UIAbilityContext): void { + this.callback.uiAbilityContext = context; + } + + setSystemChromeChangeListener(): void { + if (this.callback.callbackId == null && this.callback.applicationContext != null) { + let that = this; + this.callback.callbackId = this.callback.applicationContext.on('environment', { + onConfigurationUpdated(config) { + Log.d(PlatformPlugin.TAG, "onConfigurationUpdated: " + that.callback.showBarOrNavigation); + that.callback.platformChannel.systemChromeChanged(that.callback.showBarOrNavigation.includes('status')); + }, + onMemoryLevel(level) { + } + }) + } + } +} + +export interface PlatformPluginDelegate { + popSystemNavigator(): boolean; +} + +class PlatformPluginCallback implements PlatformMessageHandler { + private static TAG = "PlatformPluginCallback"; + platform: PlatformPlugin; + windowClass: window.Window = null; + platformChannel: PlatformChannel; + platformPluginDelegate: PlatformPluginDelegate; + context: common.Context; + showBarOrNavigation: ('status' | 'navigation')[] = ['status', 'navigation']; + uiAbilityContext: common.UIAbilityContext = null; + callbackId: number = null; + applicationContext: common.ApplicationContext = null; + currentTheme: SystemChromeStyle = null; + + playSystemSound(soundType: SoundType) { + } + + vibrateHapticFeedback(feedbackType: HapticFeedbackType) { + switch (feedbackType) { + case HapticFeedbackType.STANDARD: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'touch' }); + break; + case HapticFeedbackType.LIGHT_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'notification' }).then(); + break; + case HapticFeedbackType.MEDIUM_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'ring' }); + break; + case HapticFeedbackType.HEAVY_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'alarm' }); + break; + case HapticFeedbackType.SELECTION_CLICK: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'physicalFeedback' }); + break; + } + } + + setPreferredOrientations(ohosOrientation: number) { + Log.d(PlatformPluginCallback.TAG, "ohosOrientation: " + ohosOrientation); + this.windowClass.setPreferredOrientation(ohosOrientation); + } + + setApplicationSwitcherDescription(description: AppSwitcherDescription) { + // representation described in the given {@code description}. + } + + showSystemOverlays(overlays: SystemUiOverlay[]) { + this.setSystemChromeEnabledSystemUIOverlays(overlays); + } + + showSystemUiMode(mode: SystemUiMode) { + this.setSystemChromeEnabledSystemUIMode(mode); + } + + setSystemUiChangeListener() { + this.platform.setSystemChromeChangeListener(); + } + + restoreSystemUiOverlays() { + this.platform.updateSystemUiOverlays(); + } + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle) { + Log.d(PlatformPluginCallback.TAG, "systemUiOverlayStyle:" + JSON.stringify(systemUiOverlayStyle)); + this.setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle); + } + + popSystemNavigator() { + if (this.platformPluginDelegate != null && this.platformPluginDelegate.popSystemNavigator()) { + return; + } + if (this.uiAbilityContext != null) { + this.uiAbilityContext.terminateSelf(); + } + } + + getClipboardData(format: ClipboardContentFormat): string { + // todo + return ""; + } + + setClipboardData(text: string) { + let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + let clipboard = pasteboard.getSystemPasteboard(); + clipboard.setData(pasteData); + } + + clipboardHasStrings(): boolean { + return false; + } + + setSystemChromeEnabledSystemUIMode(mode: SystemUiMode): void { + Log.d(PlatformPluginCallback.TAG, "mode: " + mode); + let uiConfig: ('status' | 'navigation')[] = []; + if (mode == SystemUiMode.LEAN_BACK) { + //全屏显示,通过点击显示器上的任何位置都可以显示状态和导航栏 + this.windowClass.setWindowLayoutFullScreen(false); + + } else if (mode == SystemUiMode.IMMERSIVE) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,应用程序不会接收到此手势 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.IMMERSIVE_STICKY) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,此手势由应用程序接收 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.EDGE_TO_EDGE) { + //全屏显示,在应用程序上呈现状态和导航元素 + this.windowClass.setWindowLayoutFullScreen(false); + uiConfig = ['status', 'navigation']; + + } else { + return; + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } + + setSystemChromeSystemUIOverlayStyle(systemChromeStyle: SystemChromeStyle): void { + let isStatusBarLightIconValue: boolean = false; + let statusBarColorValue: string = null; + let statusBarContentColorValue: string = null; + let navigationBarColorValue: string = null; + let isNavigationBarLightIconValue: boolean = false; + let navigationBarContentColorValue: string = null; + if (systemChromeStyle.statusBarIconBrightness != null) { + switch (systemChromeStyle.statusBarIconBrightness) { + case Brightness.DARK: + isStatusBarLightIconValue = false; + break; + case Brightness.LIGHT: + isStatusBarLightIconValue = true; + break; + } + } + + if (systemChromeStyle.statusBarColor != null) { + statusBarColorValue = "#" + systemChromeStyle.statusBarColor.toString(16); + } + + if (systemChromeStyle.systemStatusBarContrastEnforced != null) { + + } + + if (systemChromeStyle.systemNavigationBarIconBrightness != null) { + switch (systemChromeStyle.systemNavigationBarIconBrightness) { + case Brightness.DARK: + isNavigationBarLightIconValue = true; + break; + case Brightness.LIGHT: + isNavigationBarLightIconValue = false; + } + } + + if (systemChromeStyle.systemNavigationBarColor != null) { + navigationBarColorValue = "#" + systemChromeStyle.systemNavigationBarColor.toString(16); + } + + if (systemChromeStyle.systemNavigationBarContrastEnforced != null) { + + } + this.currentTheme = systemChromeStyle; + let systemBarProperties = new SystemBarProperties(); + systemBarProperties.statusBarColor = statusBarColorValue; + systemBarProperties.isStatusBarLightIcon = isStatusBarLightIconValue; + systemBarProperties.statusBarContentColor = statusBarContentColorValue; + systemBarProperties.navigationBarColor = navigationBarColorValue; + systemBarProperties.isNavigationBarLightIcon = isNavigationBarLightIconValue; + systemBarProperties.navigationBarContentColor = navigationBarContentColorValue; + Log.d(PlatformPluginCallback.TAG, "systemBarProperties: " + JSON.stringify(systemBarProperties)); + this.windowClass.setWindowSystemBarProperties(systemBarProperties); + } + + setSystemChromeEnabledSystemUIOverlays(overlays: SystemUiOverlay[]): void { + let uiConfig: ('status' | 'navigation')[] = []; + if (overlays.length == 0) { + + } + for (let index = 0; index < overlays.length; ++index) { + let overlayToShow = overlays[index]; + switch (overlayToShow) { + case SystemUiOverlay.TOP_OVERLAYS: + uiConfig.push('status'); //hide navigation + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + uiConfig.push('navigation'); //hide bar + break; + } + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } +} + +class SystemBarProperties { + statusBarColor?: string; + + isStatusBarLightIcon?: boolean; + + statusBarContentColor?: string; + + navigationBarColor?: string; + + isNavigationBarLightIcon?: boolean; + + navigationBarContentColor?: string; +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6e6f6bcfb5b863a2b5c65b9f398ec5e048f4ad6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler } from './BinaryMessenger'; +import Log from '../../util/Log'; +import { BinaryReply } from './BinaryMessenger'; +import { TaskQueue } from './BinaryMessenger'; +import MessageCodec from './MessageCodec'; +import { BinaryMessenger } from './BinaryMessenger'; +/** + * A named channel for communicating with the Flutter application using basic, asynchronous message + * passing. + * + *

Messages are encoded into binary before being sent, and binary messages received are decoded + * into Java objects. The {@link MessageCodec} used must be compatible with the one used by the + * Flutter application. This can be achieved by creating a BasicMessageChannel + * counterpart of this channel on the Dart side. The static Java type of messages sent and received + * is {@code Object}, but only values supported by the specified {@link MessageCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +export default class BasicMessageChannel { + public static TAG = "BasicMessageChannel#"; + public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; + private messenger: BinaryMessenger; + private name: string; + private codec: MessageCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MessageCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Sends the specified message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param message the message, possibly null. + * @param callback a {@link Reply} callback, possibly null. + */ + send(message: T, callback?: (reply: T)=>void): void { + this.messenger.send(this.name, this.codec.encodeMessage(message), callback == null ? null : new IncomingReplyHandler(callback, this.codec)); + } + + /** + * Registers a message handler on this channel for receiving messages sent from the Flutter + * application. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming message on this channel will be handled + * silently by sending a null reply. + * + * @param handler a {@link MessageHandler}, or null to deregister. + */ + setMessageHandler(handler: MessageHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler(this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + + +export interface Reply { + /** + * Handles the specified message reply. + * + * @param reply the reply, possibly null. + */ + reply: (reply: T) => void; +} + +export interface MessageHandler { + + /** + * Handles the specified message received from Flutter. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply + * handlers. The reply may be submitted asynchronously and invoked on any thread. + * + *

Any uncaught exception thrown by this method, or the preceding message decoding, will be + * caught by the channel implementation and logged, and a null reply message will be sent back + * to Flutter. + * + *

Any uncaught exception thrown during encoding a reply message submitted to the {@link + * Reply} is treated similarly: the exception is logged, and a null reply is sent to Flutter. + * + * @param message the message, possibly null. + * @param reply a {@link Reply} for sending a single message reply back to Flutter. + */ + onMessage(message: T, reply: Reply): void; +} + +class IncomingReplyHandler implements BinaryReply { + private callback: (reply: T)=>void; + private codec: MessageCodec + + constructor(callback:(reply: T)=>void, codec: MessageCodec) { + this.callback = callback + this.codec = codec + } + + reply(reply: ArrayBuffer) { + try { + this.callback(this.codec.decodeMessage(reply)); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message reply", e); + } + } +} + +class IncomingMessageHandler implements BinaryMessageHandler { + private handler: MessageHandler + private codec: MessageCodec + + constructor(handler: MessageHandler, codec: MessageCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, callback: BinaryReply) { + try { + this.handler.onMessage( + this.codec.decodeMessage(message), + { + reply: (reply: T): void => { + callback.reply(this.codec.encodeMessage(reply)); + } + }); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message", e); + callback.reply(null); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..578436417dc4a23cfaf2c5adbb9c8340efa5795d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using unencoded binary messages, represented as {@link ByteBuffer}s. + * + *

This codec is guaranteed to be compatible with the corresponding BinaryCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, messages are represented using {@code ByteData}. + */ + +export default class BinaryCodec implements MessageCodec { + private returnsDirectByteBufferFromDecoding: boolean = false; + static readonly INSTANCE_DIRECT = new BinaryCodec(true); + + constructor(returnsDirectByteBufferFromDecoding: boolean) { + this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; + } + + encodeMessage(message: ArrayBuffer): ArrayBuffer { + return message + } + + decodeMessage(message: ArrayBuffer): ArrayBuffer { + if (message == null) { + return message; + } else if (this.returnsDirectByteBufferFromDecoding) { + return message; + } else { + return message.slice(0, message.byteLength); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..988c6a57092f7913f20b65bf6afa97b310385931 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * An abstraction over the threading policy used to invoke message handlers. + * + *

These are generated by calling methods like {@link + * BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can be passed into platform + * channels' constructors to control the threading policy for handling platform channels' + * messages. + */ +export interface TaskQueue {} + +/** Options that control how a TaskQueue should operate and be created. */ +export class TaskQueueOptions { + private isSerial = true; + + getIsSerial() { + return this.isSerial; + } + + setIsSerial(isSerial: boolean): TaskQueueOptions { + this.isSerial = isSerial; + return this; + } +} + +/** + * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also + * used in the dual capacity to handle a reply received from Flutter after sending a message. + */ +export interface BinaryReply { + /** + * Handles the specified reply. + * + * @param reply the reply payload, a direct-allocated {@link ByteBuffer} or null. Senders of + * outgoing replies must place the reply bytes between position zero and current position. + * Reply receivers can read from the buffer directly. + */ + reply(reply: ArrayBuffer): void; +} + +/** Handler for incoming binary messages from Flutter. */ +export interface BinaryMessageHandler { + /** + * Handles the specified message. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter + * reply handlers. The reply may be submitted asynchronously. + * + *

Any uncaught exception thrown by this method will be caught by the messenger + * implementation and logged, and a null reply message will be sent back to Flutter. + * + * @param message the message {@link ByteBuffer} payload, possibly null. + * @param reply A {@link BinaryReply} used for submitting a reply back to Flutter. + */ + onMessage(message: ArrayBuffer, reply: BinaryReply): void; +} + +/** + * Facility for communicating with Flutter using asynchronous message passing with binary messages. + * The Flutter Dart code should use BinaryMessages to + * participate. + * + *

{@code BinaryMessenger} is expected to be utilized from a single thread throughout the + * duration of its existence. If created on the main thread, then all invocations should take place + * on the main thread. If created on a background thread, then all invocations should take place on + * that background thread. + * + * @see BasicMessageChannel , which supports message passing with Strings and semi-structured + * messages. + * @see MethodChannel , which supports communication using asynchronous method invocation. + * @see EventChannel , which supports communication using event streams. + */ +export interface BinaryMessenger { + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue; + + /** + * Sends a binary message to the Flutter application. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + */ + send(channel: String, message: ArrayBuffer): void; + + /** + * Sends a binary message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a {@link BinaryReply} callback invoked when the Flutter application responds to + * the message, possibly null. + */ + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void; + + /** + * Registers a handler to be invoked when the Flutter application sends a message to its host + * platform. + * + *

Registration overwrites any previous registration for the same channel name. Use a null + * handler to deregister. + * + *

If no handler has been registered for a particular channel, any incoming message on that + * channel will be handled silently by sending a null reply. + * + * @param channel the name {@link String} of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + * @param taskQueue a {@link BinaryMessenger.TaskQueue} that specifies what thread will execute + * the handler. Specifying null means execute on the platform thread. + */ + //setMessageHandler(channel: String, handler: BinaryMessageHandler) + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void; + // { + // if (taskQueue != null) { + // throw new Error("setMessageHandler called with nonnull taskQueue is not supported.") + // } + // } + + /** + * Enables the ability to queue messages received from Dart. + * + *

This is useful when there are pending channel handler registrations. For example, Dart may + * be initialized concurrently, and prior to the registration of the channel handlers. This + * implies that Dart may start sending messages while plugins are being registered. + */ + enableBufferingIncomingMessages(): void; + // { + // throw new Error("enableBufferingIncomingMessages not implemented."); + // } + + /** + * Disables the ability to queue messages received from Dart. + * + *

This can be used after all pending channel handlers have been registered. + */ + disableBufferingIncomingMessages(): void; + // { + // throw new Error("disableBufferingIncomingMessages not implemented."); + // } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..166659a32e819580f2d433886f763dc453d8a597 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + * A named channel for communicating with the Flutter application using asynchronous event streams. + * + *

Incoming requests for event stream setup are decoded from binary on receipt, and Java + * responses and events are encoded into binary before being transmitted back to Flutter. The {@link + * MethodCodec} used must be compatible with the one used by the Flutter application. This can be + * achieved by creating an EventChannel + * counterpart of this channel on the Dart side. The Java type of stream configuration arguments, + * events, and error details is {@code Object}, but only values supported by the specified {@link + * MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +import Log from '../../util/Log'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; + +const TAG = "EventChannel#"; + +export default class EventChannel { + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec?: MethodCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec ? codec : StandardMethodCodec.INSTANCE + this.taskQueue = taskQueue + } + + + /** + * Registers a stream handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming stream setup requests will be handled + * silently by providing an empty stream. + * + * @param handler a {@link StreamHandler}, or null to deregister. + */ + setStreamHandler(handler: StreamHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger)); + } + } +} + +/** + * Handler of stream setup and teardown requests. + * + *

Implementations must be prepared to accept sequences of alternating calls to {@link + * #onListen(Object, EventChannel.EventSink)} and {@link #onCancel(Object)}. Implementations + * should ideally consume no resources when the last such call is not {@code onListen}. In typical + * situations, this means that the implementation should register itself with platform-specific + * event sources {@code onListen} and deregister again {@code onCancel}. + */ +export interface StreamHandler { + /** + * Handles a request to set up an event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + * @param arguments stream configuration arguments, possibly null. + * @param events an {@link EventSink} for emitting events to the Flutter receiver. + */ + onListen(args: ESObject, events: EventSink): void; + + /** + * Handles a request to tear down the most recently created event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + *

The channel implementation may call this method with null arguments to separate a pair of + * two consecutive set up requests. Such request pairs may occur during Flutter hot restart. Any + * uncaught exception thrown in this situation will be logged without notifying Flutter. + * + * @param arguments stream configuration arguments, possibly null. + */ + onCancel(args: ESObject): void; +} + +/** + * Event callback. Supports dual use: Producers of events to be sent to Flutter act as clients of + * this interface for sending events. Consumers of events sent from Flutter implement this + * interface for handling received events (the latter facility has not been implemented yet). + */ +export interface EventSink { + /** + * Consumes a successful event. + * + * @param event the event, possibly null. + */ + success(event: ESObject): void; + + /** + * Consumes an error event. + * + * @param errorCode an error code String. + * @param errorMessage a human-readable error message String, possibly null. + * @param errorDetails error details, possibly null + */ + error(errorCode: string, errorMessage: string, errorDetails: ESObject): void; + + /** + * Consumes end of stream. Ensuing calls to {@link #success(Object)} or {@link #error(String, + * String, Object)}, if any, are ignored. + */ + endOfStream(): void; +} + +class IncomingStreamRequestHandler implements BinaryMessageHandler { + private handler: StreamHandler; + private activeSink = new AtomicReference(null); + private codec: MethodCodec; + private name: string; + private messenger: BinaryMessenger; + + constructor(handler: StreamHandler, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.handler = handler; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + if (call.method == "listen") { + this.onListen(call.args, reply); + } else if (call.method == "cancel") { + this.onCancel(call.args, reply); + } else { + reply.reply(null); + } + } + + onListen(args: ESObject, callback: BinaryReply): void { + const eventSink = new EventSinkImplementation(this.activeSink, this.name, this.codec, this.messenger); + const oldSink = this.activeSink.getAndSet(eventSink); + if (oldSink != null) { + // Repeated calls to onListen may happen during hot restart. + // We separate them with a call to onCancel. + try { + this.handler.onCancel(null); + } catch (e) { + Log.e(TAG + this.name, "Failed to close existing event stream", e); + } + } + try { + this.handler.onListen(args, eventSink); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + this.activeSink.set(null); + Log.e(TAG + this.name, "Failed to open event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } + + onCancel(args: ESObject, callback: BinaryReply): void { + const oldSink = this.activeSink.getAndSet(null); + if (oldSink != null) { + try { + this.handler.onCancel(args); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + Log.e(TAG + this.name, "Failed to close event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } else { + callback.reply(this.codec.encodeErrorEnvelope("error", "No active stream to cancel", null)); + } + } +} + +class EventSinkImplementation implements EventSink { + private hasEnded = false; + private activeSink: AtomicReference; + private messenger: BinaryMessenger; + private codec: MethodCodec; + private name: string; + + constructor(activeSink: AtomicReference, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.activeSink = activeSink; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + success(event: ESObject): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send(this.name, this.codec.encodeSuccessEnvelope(event)); + } + + error(errorCode: string, errorMessage: string, errorDetails: ESObject) { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send( + this.name, this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + } + + endOfStream(): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.hasEnded = true; + this.messenger.send(this.name, null); + } +} + +class AtomicReference { + private value: T; + + constructor(value: T) { + this.value = value + } + + get(): T { + return this.value; + } + + set(newValue: T): void { + this.value = newValue; + } + + getAndSet(newValue: T) { + const oldValue = this.value; + this.value = newValue; + return oldValue; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets new file mode 100644 index 0000000000000000000000000000000000000000..03af6b520acc908d9cb63914ca2236736218aa77 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterException implements Error { + stack?: string; + message: string; + name: string; + code: string; + details: ESObject + + constructor(code: string, message: string, details: ESObject) { + this.message = message; + this.code = code; + this.details =details; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c289c6054e952a5cf7ed48b58fcfab6e343533b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; +import MethodCodec from './MethodCodec'; +import StringCodec from './StringCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, JSON messages are handled by the JSON facilities of the dart:convert package. + */ +export default class JSONMessageCodec implements MessageCodec { + static INSTANCE = new JSONMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + return StringCodec.INSTANCE.encodeMessage(JSON.stringify(message)); + } + + decodeMessage(message: ArrayBuffer): ESObject { + if (message == null) { + return null; + } + try { + const jsonStr = StringCodec.INSTANCE.decodeMessage(message); + return JSON.parse(jsonStr); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b5bf1d0891fe841d7380e0e6166ca5b82793e7b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import Log from '../../util/Log'; + +import ToolUtils from '../../util/ToolUtils'; +import FlutterException from './FlutterException'; +import JSONMessageCodec from './JSONMessageCodec'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as methods arguments and result payloads are those supported by {@link + * JSONMessageCodec}. + */ +export default class JSONMethodCodec implements MethodCodec { + static INSTANCE = new JSONMethodCodec(); + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + try { + const map: Record = { + "method": methodCall.method, "args": methodCall.args + } + + return JSONMessageCodec.INSTANCE.encodeMessage(map); + } catch (e) { + throw new Error("Invalid JSON"); + } + } + + decodeMethodCall(message: ArrayBuffer): MethodCall { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(message); + if (ToolUtils.isObj(json)) { + const method: string = json["method"]; + const args: ESObject = json["args"]; + if (typeof method == 'string') { + return new MethodCall(method, args); + } + } + throw new Error("Invalid method call: " + json); + } catch (e) { + throw new Error("Invalid JSON:" + JSON.stringify(e)); + } + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([result]); + } + + encodeErrorEnvelope(errorCode: ESObject, errorMessage: string, errorDetails: ESObject) { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(envelope); + if (json instanceof Array) { + if (json.length == 1) { + return json[0]; + } + if (json.length == 3) { + const code: string = json[0]; + const message: string = json[1]; + const details: ESObject = json[2]; + if (typeof code == 'string' && (message == null || typeof message == 'string')) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Invalid envelope: " + json); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..663d57af19c70523e44a5f48cc61e22ab0dc5b33 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * A message encoding/decoding mechanism. + */ +export default interface MessageCodec { + /** + * Encodes the specified message into binary. + */ + encodeMessage(message: T) : ArrayBuffer; + + /** + * Decodes the specified message from binary. + * + */ + decodeMessage(message: ArrayBuffer): T; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets new file mode 100644 index 0000000000000000000000000000000000000000..0042c25c3b21f484cda8158e5485bb57e73dfd82 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import ToolUtils from '../../util/ToolUtils'; +/** Command object representing a method call on a {@link MethodChannel}. */ +export default class MethodCall { + /** The name of the called method. */ + method: string; + + /** + * Arguments for the call. + * + *

Consider using {@link #arguments()} for cases where a particular run-time type is expected. + * Consider using {@link #argument(String)} when that run-time type is {@link Map} or {@link + * JSONObject}. + */ + args: ESObject; + + constructor(method: string, args: ESObject) { + this.method = method + this.args = args + } + + argument(key: string): ESObject { + if (this.args == null) { + return null; + } else if (this.args instanceof Map) { + return (this.args as Map).get(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args[key] + } else { + throw new Error("ClassCastException"); + } + } + + hasArgument(key: string): boolean { + if (arguments == null) { + return false; + } else if (arguments instanceof Map) { + return (this.args as Map).has(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args.hasOwnProperty(key); + } else { + throw new Error("ClassCastException"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..e491ed5f7fec63ad1064c7e7ddbe468aaf3821df --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; +/** + * A named channel for communicating with the Flutter application using asynchronous method calls. + * + *

Incoming method calls are decoded from binary on receipt, and Java results are encoded into + * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible + * with the one used by the Flutter application. This can be achieved by creating a MethodChannel + * counterpart of this channel on the Dart side. The Java type of method call arguments and results + * is {@code Object}, but only values supported by the specified {@link MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ + +export default class MethodChannel { + static TAG = "MethodChannel#"; + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MethodCodec = StandardMethodCodec.INSTANCE, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Invokes a method on this channel, optionally expecting a result. + * + *

Any uncaught exception thrown by the result callback will be caught and logged. + * + * @param method the name String of the method. + * @param arguments the arguments for the invocation, possibly null. + * @param callback a {@link Result} callback for the invocation result, or null. + */ + invokeMethod(method: string, args: ESObject, callback?: MethodResult): void { + this.messenger.send(this.name, this.codec.encodeMethodCall(new MethodCall(method, args)), callback == null ? null : new IncomingResultHandler(callback, this.codec)); + } + + /** + * Registers a method call handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming method call on this channel will be handled + * silently by sending a null reply. This results in a MissingPluginException + * on the Dart side, unless an OptionalMethodChannel + * is used. + * + * @param handler a {@link MethodCallHandler}, or null to deregister. + */ + setMethodCallHandler(handler: MethodCallHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + +/** A handler of incoming method calls. */ +export interface MethodCallHandler { + /** + * Handles the specified method call received from Flutter. + * + *

Handler implementations must submit a result for all incoming calls, by making a single + * call on the given {@link Result} callback. Failure to do so will result in lingering Flutter + * result handlers. The result may be submitted asynchronously and on any thread. Calls to + * unknown or unimplemented methods should be handled using {@link Result#notImplemented()}. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged, and an error result will be sent back to Flutter. + * + *

The handler is called on the platform thread (Android main thread) by default, or + * otherwise on the thread specified by the {@link BinaryMessenger.TaskQueue} provided to the + * associated {@link MethodChannel} when it was created. See also Threading in + * the Flutter Engine. + * + * @param call A {@link MethodCall}. + * @param result A {@link Result} used for submitting the result of the call. + */ + onMethodCall(call: MethodCall, result: MethodResult): void; +} + +/** + * Method call result callback. Supports dual use: Implementations of methods to be invoked by + * Flutter act as clients of this interface for sending results back to Flutter. Invokers of + * Flutter methods provide implementations of this interface for handling results received from + * Flutter. + * + *

All methods of this class can be invoked on any thread. + */ +export interface MethodResult { + /** + * Handles a successful result. + * + * @param result The result, possibly null. The result must be an Object type supported by the + * codec. For instance, if you are using {@link StandardMessageCodec} (default), please see + * its documentation on what types are supported. + */ + success: (result: ESObject) => void; + + /** + * Handles an error result. + * + * @param errorCode An error code String. + * @param errorMessage A human-readable error message String, possibly null. + * @param errorDetails Error details, possibly null. The details must be an Object type + * supported by the codec. For instance, if you are using {@link StandardMessageCodec} + * (default), please see its documentation on what types are supported. + */ + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) => void; + + /** Handles a call to an unimplemented method. */ + notImplemented: () => void; +} + +class IncomingResultHandler implements BinaryReply { + private callback: MethodResult; + private codec: MethodCodec; + + constructor(callback: MethodResult, codec: MethodCodec) { + this.callback = callback; + this.codec = codec + } + + reply(reply: ArrayBuffer): void { + try { + if (reply == null) { + this.callback.notImplemented(); + } else { + try { + this.callback.success(this.codec.decodeEnvelope(reply)); + } catch (e) { + this.callback.error(e.code, e.getMessage(), e.details); + } + } + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call result", e); + } + } +} + +class IncomingMethodCallHandler implements BinaryMessageHandler { + private handler: MethodCallHandler; + private codec: MethodCodec; + + constructor(handler: MethodCallHandler, codec: MethodCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + try { + this.handler.onMethodCall( + call, { + success: (result: ESObject): void => { + reply.reply(this.codec.encodeSuccessEnvelope(result)); + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject): void => { + reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + }, + + notImplemented: (): void => { + Log.w(MethodChannel.TAG,"method not implemented"); + reply.reply(null); + } + }); + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call", e); + reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..86ed92aca6d512fa8247d963619acf67f29b7fe4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from './MethodCall'; +/** + * A codec for method calls and enveloped results. + * + *

Method calls are encoded as binary messages with enough structure that the codec can extract a + * method name String and an arguments Object. These data items are used to populate a {@link + * MethodCall}. + * + *

All operations throw {@link IllegalArgumentException}, if conversion fails. + */ +export default interface MethodCodec { + /** + * Encodes a message call into binary. + * + * @param methodCall a {@link MethodCall}. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeMethodCall(methodCall: MethodCall): ArrayBuffer; + + /** + * Decodes a message call from binary. + * + * @param methodCall the binary encoding of the method call as a {@link ByteBuffer}. + * @return a {@link MethodCall} representation of the bytes between the given buffer's current + * position and its limit. + */ + decodeMethodCall(methodCall: ArrayBuffer): MethodCall; + + /** + * Encodes a successful result into a binary envelope message. + * + * @param result The result value, possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeSuccessEnvelope(result: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message with the native stacktrace. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @param errorStacktrace Platform stacktrace for the error. possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer + + /** + * Decodes a result envelope from binary. + * + * @param envelope the binary encoding of a result envelope as a {@link ByteBuffer}. + * @return the enveloped result Object. + * @throws FlutterException if the envelope was an error envelope. + */ + decodeEnvelope(envelope: ArrayBuffer): ESObject +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb92c8eb1acc0406e2f14229e8d29d0ef19b3030 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets @@ -0,0 +1,14 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..3de7603e1f576a9af23be11b9f185c67730429b3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets @@ -0,0 +1,310 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * MessageCodec using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMessageCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Supported messages are acyclic values of these forms: + * + *

    + *
  • null + *
  • Booleans + *
  • number + *
  • BigIntegers (see below) + *
  • Int8Array, Int32Array, Float32Array, Float64Array + *
  • Strings + *
  • Array[] + *
  • Lists of supported values + *
  • Maps with supported keys and values + *
+ * + *

On the Dart side, these values are represented as follows: + * + *

    + *
  • null: null + *
  • Boolean: bool + *
  • Byte, Short, Integer, Long: int + *
  • Float, Double: double + *
  • String: String + *
  • byte[]: Uint8List + *
  • int[]: Int32List + *
  • long[]: Int64List + *
  • float[]: Float32List + *
  • double[]: Float64List + *
  • List: List + *
  • Map: Map + *
+ * + *

BigIntegers are represented in Dart as strings with the hexadecimal representation of the + * integer's value. + * + *

To extend the codec, overwrite the writeValue and readValueOfType methods. + */ +export default class StandardMessageCodec implements MessageCodec { + private static TAG = "StandardMessageCodec#"; + static INSTANCE = new StandardMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + const stream = ByteBuffer.from(new ArrayBuffer(1024)) + this.writeValue(stream, message); + return stream.buffer + } + + decodeMessage(message: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(message) + return this.readValue(buffer) + } + + private static NULL = 0; + private static TRUE = 1; + private static FALSE = 2; + private static INT32 = 3; + private static INT64 = 4; + private static BIGINT = 5; + private static FLOAT64 = 6; + private static STRING = 7; + private static UINT8_ARRAY = 8; + private static INT32_ARRAY = 9; + private static INT64_ARRAY = 10; + private static FLOAT64_ARRAY = 11; + private static LIST = 12; + private static MAP = 13; + private static FLOAT32_ARRAY = 14; + + + writeValue(stream: ByteBuffer, value: ESObject): ESObject { + if (value == null || value == undefined) { + stream.writeInt8(StandardMessageCodec.NULL) + } else if (typeof value === "boolean") { + stream.writeInt8(value ? StandardMessageCodec.TRUE : StandardMessageCodec.FALSE) + } else if (typeof value === "number") { + if (Number.isInteger(value)) { //整型 + if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { + stream.writeInt8(StandardMessageCodec.INT32) + stream.writeInt32(value, true) + } else { + stream.writeInt8(StandardMessageCodec.INT64) + stream.writeInt64(value, true) + } + } else { //浮点型 + stream.writeInt8(StandardMessageCodec.FLOAT64) + this.writeAlignment(stream, 8); + stream.writeFloat64(value, true) + } + } else if (typeof value === "string") { + stream.writeInt8(StandardMessageCodec.STRING) + let stringBuff = StringUtils.stringToArrayBuffer(value) + this.writeBytes(stream, new Uint8Array(stringBuff)) + } else if (value instanceof Uint8Array) { + stream.writeInt8(StandardMessageCodec.UINT8_ARRAY) + this.writeBytes(stream, value) + } else if (value instanceof Int32Array) { + stream.writeInt8(StandardMessageCodec.INT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeInt32(item, true)) + } else if (value instanceof Float32Array) { + stream.writeInt8(StandardMessageCodec.FLOAT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeFloat32(item, true)) + } else if (value instanceof Float64Array) { + stream.writeInt8(StandardMessageCodec.FLOAT64_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 8); + value.forEach(item => stream.writeFloat64(item, true)) + } else if (value instanceof Array) { + stream.writeInt8(StandardMessageCodec.LIST) + this.writeSize(stream, value.length); + value.forEach((item: ESObject): void => this.writeValue(stream, item)) + } else if (value instanceof Map) { + stream.writeInt8(StandardMessageCodec.MAP) + this.writeSize(stream, value.size); + value.forEach((value: ESObject, key: ESObject) => { + this.writeValue(stream, key); + this.writeValue(stream, value); + }) + } else if (typeof value == 'object') { + this.writeValue(stream, new Map(value.entries())) + } + return stream + } + + writeAlignment(stream: ByteBuffer, alignment: number) { + let mod: number = stream.byteOffset % alignment; + if (mod != 0) { + for (let i = 0; i < alignment - mod; i++) { + stream.writeInt8(0); + } + } + } + + writeSize(stream: ByteBuffer, value: number) { + if (value < 254) { + stream.writeInt8(value); + } else if (value <= 0xffff) { + stream.writeInt8(254); + stream.writeInt16(value, true); + } else { + stream.writeInt8(255); + stream.writeInt32(value, true); + } + } + + writeBytes(stream: ByteBuffer, bytes: Uint8Array) { + this.writeSize(stream, bytes.length) + bytes.forEach(item => stream.writeInt8(item)) + } + + readSize(buffer: ByteBuffer) { + let value = buffer.readInt8() & 0xff; + if (value < 254) { + return value; + } else if (value == 254) { + return buffer.readInt16(true); + } else { + return buffer.readInt32(true); + } + } + + readAlignment(buffer: ByteBuffer, alignment: number) { + let mod = buffer.byteOffset % alignment; + if (mod != 0) { + buffer.skip(alignment - mod); + } + } + + readValue(buffer: ByteBuffer): ESObject { + let type = buffer.readInt8() + return this.readValueOfType(type, buffer); + } + + readBytes(buffer: ByteBuffer): Uint8Array { + let length = this.readSize(buffer); + let bytes = new Uint8Array(length) + for (let i = 0; i < length; i++) { + bytes[i] = buffer.readUint8() + } + return bytes; + } + + readValueOfType(type: number, buffer: ByteBuffer): ESObject { + let result: ESObject; + switch (type) { + case StandardMessageCodec.NULL: + result = null; + break; + case StandardMessageCodec.TRUE: + result = true; + break; + case StandardMessageCodec.FALSE: + result = false; + break; + case StandardMessageCodec.INT32: + result = buffer.readInt32(true); + break; + case StandardMessageCodec.INT64: + result = buffer.readInt64(true); + break; + case StandardMessageCodec.BIGINT: + result = buffer.readBigInt64(true) + case StandardMessageCodec.FLOAT64: + this.readAlignment(buffer, 8); + result = buffer.readFloat64(true) + break; + case StandardMessageCodec.STRING: { + let bytes = this.readBytes(buffer); + result = StringUtils.arrayBufferToString(bytes.buffer); + break; + } + case StandardMessageCodec.UINT8_ARRAY: { + result = this.readBytes(buffer); + break; + } + case StandardMessageCodec.INT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Int32Array(length) + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt32(true) + } + result = array; + break; + } + case StandardMessageCodec.INT64_ARRAY: { //这里是都城array 还是 bigint待定 + let length = this.readSize(buffer); + let array: Array = new Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt64(true) + } + result = array; + break; + } + case StandardMessageCodec.FLOAT64_ARRAY: { + let length = this.readSize(buffer); + let array = new Float64Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat64(true) + } + result = array; + break; + } + case StandardMessageCodec.LIST: { + let length = this.readSize(buffer); + let array: Array = new Array(length) + for (let i = 0; i < length; i++) { + array[i] = this.readValue(buffer) + } + result = array; + break; + } + case StandardMessageCodec.MAP: { + let size = this.readSize(buffer); + let map: Map = new Map() + for (let i = 0; i < size; i++) { + map.set(this.readValue(buffer), this.readValue(buffer)); + } + result = map; + break; + } + case StandardMessageCodec.FLOAT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Float32Array(length); + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat32(true) + } + result = array; + break; + } + default: + throw new Error("Message corrupted"); + } + return result; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4417c54eb56d55355b73104ee8626a17836735f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import FlutterException from './FlutterException'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMessageCodec from './StandardMessageCodec'; + +/** + * A {@link MethodCodec} using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMethodCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as method arguments and result payloads are those supported by {@link + * StandardMessageCodec}. + */ +export default class StandardMethodCodec implements MethodCodec { + private static TAG = "StandardMethodCodec"; + public static INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE); + + private messageCodec: StandardMessageCodec; + + /** Creates a new method codec based on the specified message codec. */ + constructor(messageCodec: StandardMessageCodec) { + this.messageCodec = messageCodec; + } + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + this.messageCodec.writeValue(stream, methodCall.method); + this.messageCodec.writeValue(stream, methodCall.args); + return stream.buffer; + } + + decodeMethodCall(methodCall: ArrayBuffer): MethodCall { + const buffer = ByteBuffer.from(methodCall); + const method: ESObject = this.messageCodec.readValue(buffer); + const args: ESObject = this.messageCodec.readValue(buffer); + if (typeof method == 'string' && !buffer.hasRemaining()) { + return new MethodCall(method, args); + } + throw new Error("Method call corrupted"); + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(0); + this.messageCodec.writeValue(stream, result); + return stream.buffer; + } + + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + return stream.buffer; + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + this.messageCodec.writeValue(stream, errorStacktrace); + return stream.buffer; + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(envelope); + const flag = buffer.readInt8(); + switch (flag) { + case 0: { + const result: ESObject = this.messageCodec.readValue(buffer); + if (!buffer.hasRemaining()) { + return result; + } + // Falls through intentionally. + } + case 1: { + const code: ESObject = this.messageCodec.readValue(buffer); + const message: ESObject = this.messageCodec.readValue(buffer); + const details: ESObject = this.messageCodec.readValue(buffer); + if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Envelope corrupted"); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..e43be76b5527f6180d9b30ede5c1c07dff84c729 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using UTF-8 encoded String messages. + * + *

This codec is guaranteed to be compatible with the corresponding StringCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + */ +export default class StringCodec implements MessageCodec { + static readonly INSTANCE = new StringCodec(); + + encodeMessage(message: string): ArrayBuffer { + if (message == null) { + return null; + } + return StringUtils.stringToArrayBuffer(message); + } + + decodeMessage(message: ArrayBuffer): string { + if (message == null) { + return null; + } + return StringUtils.arrayBufferToString(message); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets new file mode 100644 index 0000000000000000000000000000000000000000..72735c0a29a1e893e8bf986458cea0da82df0d2b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TextEditState } from '../../embedding/engine/systemchannels/TextInputChannel'; +import Log from '../../util/Log'; +import inputMethod from '@ohos.inputMethod'; +import ArrayList from '@ohos.util.ArrayList'; +import { TextEditingDelta } from './TextEditingDelta'; + +const TAG = "ListenableEditingState"; +export class ListenableEditingState { + //Cache used to storage software keyboard input action + private mStringCache: string; + private mSelectionStartCache: number; + private mSelectionEndCache: number; + private mComposingStartCache: number; + private mComposingEndCache: number; + //used to compare with Cache + private mTextInputState: TextEditState; + private mListeners: ArrayList = new ArrayList(); + private mPendingListeners: ArrayList = new ArrayList(); + private mBatchTextEditingDeltas: ArrayList = new ArrayList(); + private mChangeNotificationDepth: number; + private mBatchEditNestDepth: number; + + private mTextWhenBeginBatchEdit: string; + private mSelectionStartWhenBeginBatchEdit: number; + private mSelectionEndWhenBeginBatchEdit: number; + private mComposingStartWhenBeginBatchEdit: number; + private mComposingEndWhenBeginBatchEdit: number; + + + constructor() { + this.mStringCache = ""; + this.mSelectionStartCache = 0; + this.mSelectionEndCache = 0; + this.mComposingStartCache = -1; + this.mComposingEndCache = -1; + } + + + getSelectionStart(): number { + return this.mSelectionStartCache; + } + + getSelectionEnd(): number { + return this.mSelectionEndCache; + } + + getComposingStart(): number { + return this.mComposingStartCache; + } + + getComposingEnd(): number { + return this.mComposingEndCache; + } + + getStringCache(): string { + return this.mStringCache; + } + + setSelectionStart(newSelectionStart: number): void { + this.mSelectionStartCache = newSelectionStart; + } + + setSelectionEnd(newSelectionEnd: number): void { + this.mSelectionEndCache = newSelectionEnd; + } + + setComposingStart(newComposingStart: number): void { + this.mComposingStartCache = newComposingStart; + } + + setComposingEnd(newComposingEnd: number): void { + this.mComposingEndCache = newComposingEnd; + } + + setStringCache(newStringCache: string): void { + this.mStringCache = newStringCache; + } + + notifyListener(listener: EditingStateWatcher, + textChanged: boolean, + selectionChanged: boolean, + composingChanged: boolean): void { + this.mChangeNotificationDepth++; + listener.didChangeEditingState(textChanged, selectionChanged, composingChanged); + this.mChangeNotificationDepth--; + } + + notifyListenersIfNeeded(textChanged: boolean, selectionChanged: boolean, composingChanged: boolean) { + if (textChanged || selectionChanged || composingChanged) { + for(const listener of this.mListeners) { + this.notifyListener(listener, textChanged, selectionChanged, composingChanged); + } + + } + } + + handleInsertTextEvent(text: string): void { + if(this.mTextInputState == null) { + Log.e(TAG, "mTextInputState is null"); + } + if(this.mStringCache.length == this.mSelectionStartCache) { + //Insert text one by one + this.mStringCache += text; + this.setSelectionStart(this.mStringCache.length); + this.setSelectionEnd(this.mStringCache.length); + + } else if(this.mStringCache.length > this.mSelectionStartCache) { + //Insert text in the middle of string + let tempStr: string = this.mStringCache.substring(0, this.mSelectionStartCache) + text + this.mStringCache.substring(this.mSelectionStartCache); + this.mStringCache = tempStr; + this.mSelectionStartCache += text.length; + this.mSelectionEndCache = this.mSelectionStartCache; + } + if(this.mListeners == null) { + Log.e(TAG, "mListeners is null"); + return; + } + this.notifyListenersIfNeeded(true, true, false); + } + + updateTextInputState(state: TextEditState): void { + this.beginBatchEdit(); + this.setStringCache(state.text); + if(state.hasSelection()) { + this.setSelectionStart(state.selectionStart); + this.setSelectionEnd(state.selectionEnd); + } else { + this.setSelectionStart(0); + this.setSelectionEnd(0); + } + this.endBatchEdit(); + } + + beginBatchEdit(): void { + this.mBatchEditNestDepth++; + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "editing state should not be changed in a listener callback"); + } + if(this.mBatchEditNestDepth == 1 && !this.mListeners.isEmpty()) { + this.mTextWhenBeginBatchEdit = this.getStringCache(); + this.mSelectionStartWhenBeginBatchEdit = this.getSelectionStart(); + this.mSelectionEndWhenBeginBatchEdit = this.getSelectionEnd(); + this.mComposingStartWhenBeginBatchEdit = this.getComposingStart(); + this.mComposingEndWhenBeginBatchEdit = this.getComposingEnd(); + } + } + + endBatchEdit(): void { + if (this.mBatchEditNestDepth == 0) { + Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit"); + return; + } + if(this.mBatchEditNestDepth == 1) { + Log.d(TAG,"mBatchEditNestDepth == 1"); + for(const listener of this.mPendingListeners) { + this.notifyListener(listener, true, true, true); + } + + if(!this.mListeners.isEmpty()) { + Log.d(TAG, "didFinishBatchEdit with " + this.mListeners.length + " listener(s)"); + const textChanged = !(this.mStringCache == this.mTextWhenBeginBatchEdit); + const selectionChanged = this.mSelectionStartWhenBeginBatchEdit != this.getSelectionStart() + || this.mSelectionEndWhenBeginBatchEdit != this.getSelectionEnd(); + const composingRegionChanged = this.mComposingStartWhenBeginBatchEdit != this.getComposingStart() + || this.mComposingEndWhenBeginBatchEdit != this.getComposingEnd(); + Log.d(TAG,"textChanged: " + textChanged + " selectionChanged: " + selectionChanged + + " composingRegionChanged: " + composingRegionChanged); + this.notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged); + } + } + for(const listener of this.mPendingListeners) { + this.mListeners.add(listener); + } + this.mPendingListeners.clear(); + this.mBatchEditNestDepth--; + + } + + addEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "adding a listener " + JSON.stringify(listener) + " in a listener callback"); + } + if(this.mBatchEditNestDepth > 0) { + Log.d(TAG, "a listener was added to EditingState while a batch edit was in progress"); + this.mPendingListeners.add(listener); + } else { + this.mListeners.add(listener); + } + } + + removeEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "removing a listener " + JSON.stringify(listener) + " in a listener callback"); + } + this.mListeners.remove(listener); + if(this.mBatchEditNestDepth > 0) { + this.mPendingListeners.remove(listener); + } + } + + handleDeleteEvent(leftOrRight: boolean, length: number): void { + if(leftOrRight == false) { + //delete left + if(this.mSelectionStartCache == 0) { + return; + } + this.mSelectionStartCache -= length; + let tempStr: string = this.mStringCache.slice(0, this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionStartCache + length); + this.mStringCache = tempStr; + this.mSelectionEndCache = this.mSelectionStartCache; + } else if(leftOrRight == true) { + //delete right + if(this.mSelectionStartCache == this.mStringCache.length) { + return; + } + this.mSelectionEndCache += length; + let tempStr: string = this.mStringCache.slice(0,this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionEndCache); + this.mStringCache = tempStr; + this.mSelectionStartCache = this.mSelectionEndCache; + } + this.notifyListenersIfNeeded(true, true, false); + } + + handleFunctionKey(functionKey: inputMethod.FunctionKey): void { + switch (functionKey.enterKeyType) { + case inputMethod.EnterKeyType.PREVIOUS: + case inputMethod.EnterKeyType.UNSPECIFIED: + case inputMethod.EnterKeyType.NONE: + case inputMethod.EnterKeyType.GO: + case inputMethod.EnterKeyType.SEARCH: + case inputMethod.EnterKeyType.SEND: + case inputMethod.EnterKeyType.NEXT: + case inputMethod.EnterKeyType.DONE: + + } + } + + handleSelectByRange(range: inputMethod.Range): void { + Log.d(TAG, "handleSelectByRange start: " + range.start +" end: " + range.end); + } + + + +} + +export interface EditingStateWatcher { + // Changing the editing state in a didChangeEditingState callback may cause unexpected + // behavior. + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets new file mode 100644 index 0000000000000000000000000000000000000000..c61296f6dae8b30fcb035f72d8457ca36d83a015 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; + +export class TextEditingDelta { + private static TAG = "TextEditingDelta"; + private oldText: string; + private deltaText: string; + private deltaStart: number; + private deltaEnd: number; + private newSelectionStart: number; + private newSelectionEnd: number; + private newComposingStart: number; + private newComposingEnd: number; + + constructor(oldEditable: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number, + replacementDestinationStart?: number, + replacementDestinationEnd?: number, + replacementSource?: string,) { + this.newSelectionStart = selectionStart; + this.newSelectionEnd = selectionEnd; + this.newComposingStart = composingStart; + this.newComposingEnd = composingEnd; + if(replacementDestinationStart === undefined || + replacementDestinationEnd === undefined || + replacementSource === undefined) { + this.setDeltas(oldEditable, "", -1, -1); + } else { + this.setDeltas( + oldEditable, + replacementSource, + replacementDestinationStart, + replacementDestinationEnd); + } + + } + + setDeltas(oldText: string, newText: string, newStart: number, newExtent: number): void { + this.oldText = oldText; + this.deltaText = newText; + this.deltaStart = newStart; + this.deltaEnd = newExtent; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..6df66b9cfde51d0d47c80b693b28f1f049c38b09 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import TextInputChannel, { Configuration, TextEditState, + TextInputMethodHandler, + TextInputType } from '../../embedding/engine/systemchannels/TextInputChannel'; +import inputMethod from '@ohos.inputMethod'; +import Log from '../../util/Log'; +import { EditingStateWatcher, ListenableEditingState } from './ListenableEditingState'; + +export default class TextInputPlugin implements EditingStateWatcher{ + private static TAG = "TextInputPlugin"; + private textInputChannel: TextInputChannel; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private mEditable: ListenableEditingState; + + constructor(textInputChannel: TextInputChannel) { + this.textInputChannel = textInputChannel; + this.mEditable = new ListenableEditingState(); + this.inputMethodController = inputMethod.getController(); + let textInputMethodHandler = new TextInputMethodHandlerImpl(this); + this.textInputChannel.setTextInputMethodHandler(textInputMethodHandler); + } + + public clearTextInputClient() { + this.textInputChannel.textInputMethodHandler.clearClient(); + } + setTextInputEditingState(state: TextEditState) { + + } + + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void { + this.textInputChannel.updateEditingState(this.inputTarget.id, this.mEditable.getStringCache(), + this.mEditable.getSelectionStart(), this.mEditable.getSelectionEnd(), + this.mEditable.getComposingStart(), this.mEditable.getComposingEnd()) + } + + detach(): void { + this.inputMethodController.detach((err) => { + if(err) { + Log.e(TextInputPlugin.TAG, "Failed to detach: " + JSON.stringify(err)); + } + }) + } + +} + +class TextInputMethodHandlerImpl implements TextInputMethodHandler { + private static TAG = "TextInputMethodHandlerImpl"; + private textConfig: inputMethod.TextConfig; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private configuration: Configuration; + private mEditable: ListenableEditingState; + private mRestartInputPending: boolean; + private plugin: EditingStateWatcher; + + private imcFlag: boolean = false; + + constructor(plugin: EditingStateWatcher) { + this.textConfig = { + inputAttribute: { + textInputType: 0, + enterKeyType: 1 + }}; + this.plugin = plugin; + } + + show(): void { + this.showTextInput(); + } + + hide(): void { + this.hideTextInput(); + } + + requestAutofill(): void { + + } + + finishAutofillContext(shouldSave: boolean): void { + + } + + setClient(textInputClientId: number, configuration: Configuration): void { + Log.d(TextInputMethodHandlerImpl.TAG,"textInputClientId: " + textInputClientId); + this.setTextInputClient(textInputClientId, configuration); + } + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void { + + } + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void { + + } + + setEditingState(editingState: TextEditState): void { + Log.d(TextInputMethodHandlerImpl.TAG, "text:" + editingState.text +" selectionStart:" + editingState.selectionStart + " selectionEnd:" + + editingState.selectionEnd + " composingStart:" + editingState.composingStart + " composingEnd" + editingState.composingEnd); + this.mEditable.updateTextInputState(editingState); + } + + clearClient(): void { + this.clearTextInputClient(); + } + + private async showTextInput(): Promise { + await this.attach(true); + if(this.imcFlag != true) { + this.listenKeyBoardEvent(); + } + this.inputMethodController.showTextInput().then(()=> { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in showing softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to show softKeyboard:" + JSON.stringify(err)); + }); + } + + private async hideTextInput(): Promise { + this.inputMethodController.hideTextInput().then(() => { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in hide softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to hide softKeyboard:" + JSON.stringify(err)); + }) + } + + async attach(showKeyboard: boolean): Promise { + try { + await this.inputMethodController.attach(showKeyboard, this.textConfig); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to attach:" + JSON.stringify(err)); + } + } + + setTextInputClient(client: number, configuration: Configuration): void { + this.configuration = configuration; + if(this.canShowTextInput()) { + this.inputTarget = new InputTarget(Type.FRAMEWORK_CLIENT, client); + } else { + this.inputTarget = new InputTarget(Type.NO_TARGET, client); + } + this.mEditable.removeEditingStateListener(this.plugin); + this.mEditable = new ListenableEditingState(); + + this.mRestartInputPending = true; + this.mEditable.addEditingStateListener(this.plugin); + } + + canShowTextInput(): boolean { + if(this.configuration == null || this.configuration.inputType == null) { + return true; + } + return this.configuration.inputType.type != TextInputType.NONE; + } + + listenKeyBoardEvent(): void { + try { + this.inputMethodController.on('insertText', (text) => { + Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); + this.mEditable.handleInsertTextEvent(text); + }); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteLeft', (length) => { + this.mEditable.handleDeleteEvent(false, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteRight', (length) => { + this.mEditable.handleDeleteEvent(true, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('sendFunctionKey', (functionKey) => { + this.mEditable.handleFunctionKey(functionKey); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('selectByRange', (range: inputMethod.Range) => { + this.mEditable.handleSelectByRange(range); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + Log.d(TextInputMethodHandlerImpl.TAG, "listenKeyBoardEvent success"); + this.imcFlag = true; + } + + cancelListenKeyBoardEvent(): void { + this.inputMethodController.off('insertText'); + this.inputMethodController.off('deleteLeft'); + this.inputMethodController.off('deleteRight'); + this.inputMethodController.off('sendFunctionKey'); + this.inputMethodController.off('selectByRange'); + } + + public clearTextInputClient(): void { + if(this.inputTarget.type == Type.VIRTUAL_DISPLAY_PLATFORM_VIEW) { + return; + } + this.mEditable.removeEditingStateListener(this.plugin); + this.configuration = null; + this.inputTarget = new InputTarget(Type.NO_TARGET, 0); + } +} + +enum Type { + NO_TARGET, + // InputConnection is managed by the TextInputPlugin, and events are forwarded to the Flutter + // framework. + FRAMEWORK_CLIENT, + // InputConnection is managed by a platform view that is presented on a virtual display. + VIRTUAL_DISPLAY_PLATFORM_VIEW, + PHYSICAL_DISPLAY_PLATFORM_VIEW, +} + +export class InputTarget { + type: Type; + id: number; + + constructor(type: Type, id: number) { + this.type = type; + this.id = id; + } + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..44c94a11aa2f132f6dd24b3484bb5ca9b59c940c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MouseCursorChannel, { MouseCursorMethodHandler } from '../../embedding/engine/systemchannels/MouseCursorChannel'; +import pointer from '@ohos.multimodalInput.pointer'; +import HashMap from '@ohos.util.HashMap'; +import Log from '../../util/Log'; +import { AsyncCallback } from '@ohos.base'; + +const TAG: string = "MouseCursorPlugin"; +export default class MouseCursorPlugin implements MouseCursorMethodHandler{ + private mView: MouseCursorViewDelegate; + + private mouseCursorChannel: MouseCursorChannel; + + private systemCursorConstants: HashMap; + + constructor(mouseCursorView: MouseCursorViewDelegate, mouseCursorChannel: MouseCursorChannel) { + this.mView = mouseCursorView; + this.mouseCursorChannel = mouseCursorChannel; + this.mouseCursorChannel.setMethodHandler(this); + } + + activateSystemCursor(kind: string): void { + this.mView.getWindowId((error, windowId) => { + if (windowId < 0) { + Log.w(TAG, "set point style failed windowId is invalid"); + return; + } + let pointStyle: pointer.PointerStyle = this.resolveSystemCursor(kind); + try { + pointer.setPointerStyle(windowId, pointStyle, (err: ESObject) => { + Log.i(TAG, "set point style success kind : " + kind); + }) + } catch (e) { + Log.e(TAG, "set point style failed : " + kind + " " + JSON.stringify(e)); + } + }); + } + + /** + * Return mouse cursor point style + * + *

This method guarantees to return a non-null object. + * + * @param kind mouse cursor type + * @returns point style + */ + private resolveSystemCursor(kind: string): pointer.PointerStyle { + if (this.systemCursorConstants == null) { + this.systemCursorConstants = new HashMap(); + this.systemCursorConstants.set("alias", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("allScroll", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("basic", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("cell", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("click", pointer.PointerStyle.HAND_POINTING); + this.systemCursorConstants.set("contextMenu", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("copy", pointer.PointerStyle.CURSOR_COPY); + this.systemCursorConstants.set("forbidden", pointer.PointerStyle.CURSOR_FORBID); + this.systemCursorConstants.set("grab", pointer.PointerStyle.HAND_OPEN); + this.systemCursorConstants.set("grabbing", pointer.PointerStyle.HAND_GRABBING); + this.systemCursorConstants.set("help", pointer.PointerStyle.HELP); + this.systemCursorConstants.set("move", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("none", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("noDrop", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("precise", pointer.PointerStyle.CROSS); + this.systemCursorConstants.set("text", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("resizeColum", pointer.PointerStyle.NORTH_SOUTH); + this.systemCursorConstants.set("resizeDown", pointer.PointerStyle.SOUTH); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeDownRight", pointer.PointerStyle.SOUTH_EAST); + this.systemCursorConstants.set("resizeLeft", pointer.PointerStyle.WEST); + this.systemCursorConstants.set("resizeLeftRight", pointer.PointerStyle.RESIZE_LEFT_RIGHT); + this.systemCursorConstants.set("resizeRight", pointer.PointerStyle.EAST); + this.systemCursorConstants.set("resizeRow", pointer.PointerStyle.WEST_EAST); + this.systemCursorConstants.set("resizeUp", pointer.PointerStyle.NORTH); + this.systemCursorConstants.set("resizeUpDown", pointer.PointerStyle.RESIZE_UP_DOWN); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeUpRight", pointer.PointerStyle.NORTH_EAST); + this.systemCursorConstants.set("resizeUpLeftDownRight", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("resizeUpRightDownLeft", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("verticalText", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("wait", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("zoomIn", pointer.PointerStyle.ZOOM_IN); + this.systemCursorConstants.set("zoomOut", pointer.PointerStyle.ZOOM_OUT); + } + let pointStyle:pointer.PointerStyle = this.systemCursorConstants.get(kind); + if (pointStyle === null) { + return pointer.PointerStyle.DEFAULT; + } + return pointStyle; + } + + /** + * Detaches the text input plugin from the platform views controller; + * + *

The MouseCursorPlugin instance should not be used after call this. + */ + destroy(): void { + this.mouseCursorChannel.setMethodHandler(null); + } +} + +/** + * Delegate interface for requesting the system to display a pointer icon object. + * + *

Typically implemented by an component, such as a{@code FlutterView} + */ +export interface MouseCursorViewDelegate { + /** + * get window id to set mouse style + *

component need to implement this interface to get windowId + * + * @param callback windowId + * */ + getWindowId(callback: AsyncCallback): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..faa3bc90e50c304744883689a532d0dc323bd714 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export class AccessibilityEventsDelegate { + private accessibilityBridge: AccessibilityBridge; + + requestSendAccessibilityEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + onAccessibilityHoverEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + setAccessibilityBridge (accessibilityBridge: AccessibilityBridge): void { + this.accessibilityBridge = accessibilityBridge; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets new file mode 100644 index 0000000000000000000000000000000000000000..64e8c7f780dc9253f3fd79c05663805a13c8d839 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; + +export class PlatformOverlayView { + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + + constructor(context: Context, width: Number, height: Number, accessibilityEventsDelegate: AccessibilityEventsDelegate) { + this.accessibilityEventsDelegate= accessibilityEventsDelegate; + } + + public onHoverEvent(): boolean { + return false; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets new file mode 100644 index 0000000000000000000000000000000000000000..ddf5f59a71c4d1c7d51082bcf104990e0faa08c6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DynamicView } from '../../view/DynamicView/dynamicView' + +/** A handle to an DynamicView to be embedded in the Flutter hierarchy. */ +export default abstract class PlatformView { + /** Returns the DynamicView to be embedded in the Flutter hierarchy. */ + abstract getView(): DVModel; + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is + * associated with the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} can now + * render a UI and interact with the user. + * + *

Some platform views may have unusual dependencies on the {@link View} that renders Flutter + * UIs, such as unique keyboard interactions. That {@link View} is provided here for those + * purposes. Use of this {@link View} should be avoided if it is not absolutely necessary, because + * depending on this {@link View} will tend to make platform view code more brittle to future + * changes. + */ + onFlutterViewAttached(dvModel: DVModel): void {} + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is detached + * and disassociated from the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} no longer + * has a rendering surface, or a user interaction surface of any kind. + * + *

This platform view must release any references related to the DynamicView that was + * provided in {@link #onFlutterViewAttached(View)}. + */ + onFlutterViewDetached(): void {} + + /** + * Dispose this platform view. + * + *

The {@link PlatformView} object is unusable after this method is called. + * + *

Plugins implementing {@link PlatformView} must clear all references to the View object and + * the PlatformView after this method is called. Failing to do so will result in a memory leak. + * + *

References related to the DynamicView attached in {@link + * #onFlutterViewAttached(View)} must be released in {@code dispose()} to avoid memory leaks. + */ + abstract dispose(): void; + + /** + * Callback fired when the platform's input connection is locked, or should be used. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionLocked(): void {} + + /** + * Callback fired when the platform input connection has been unlocked. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionUnlocked(): void {} +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..373a7ea5a5906c812c330762fd3825d4ce420201 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from '../common/MessageCodec'; +import PlatformView from './PlatformView' +import common from '@ohos.app.ability.common'; + +export default abstract class PlatformViewFactory { + private createArgsCodec: MessageCodec; + + /** @param createArgsCodec the codec used to decode the args parameter of {@link #create}. */ + constructor(createArgsCodec: MessageCodec) { + this.createArgsCodec = createArgsCodec; + } + + /** + * Creates a new Dynamic be embedded in the Flutter hierarchy. + * + * @param context the context to be used when creating the view, this is different than + * FlutterView's context. + * @param viewId unique identifier for the created instance, this value is known on the Dart side. + * @param args arguments sent from the Flutter app. The bytes for this value are decoded using the + * createArgsCodec argument passed to the constructor. This is null if createArgsCodec was + * null, or no arguments were sent from the Flutter app. + */ + public abstract create(context: common.Context, viewId: number, args: ESObject): PlatformView; + + /** Returns the codec to be used for decoding the args parameter of {@link #create}. */ + getCreateArgsCodec(): MessageCodec { + return this.createArgsCodec; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c49f5eeaddb54cece120df8eea307c69ad76ebf --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PlatformViewFactory from './PlatformViewFactory' + +/** + * Registry for platform view factories. + * + *

Plugins can register factories for specific view types. + */ +export default interface PlatformViewRegistry { + /** + * Registers a factory for a platform view. + * + * @param viewTypeId unique identifier for the platform view's type. + * @param factory factory for creating platform views of the specified type. + * @return true if succeeded, false if a factory is already registered for viewTypeId. + */ + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets new file mode 100644 index 0000000000000000000000000000000000000000..98cb247d890cbe65150feb84242c01128047e7f9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import PlatformViewFactory from './PlatformViewFactory' +import PlatformViewRegistry from './PlatformViewRegistry' + +export default class PlatformViewRegistryImpl implements PlatformViewRegistry { + // Maps a platform view type id to its factory. + private viewFactories: HashMap; + + constructor() { + this.viewFactories = new HashMap(); + } + + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { + if (this.viewFactories.hasKey(viewTypeId)) { + return false; + } + + this.viewFactories.set(viewTypeId, factory); + return true; + } + + getFactory(viewTypeId: string): PlatformViewFactory { + return this.viewFactories.get(viewTypeId); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..c34d9bcce565e65f3eebb5cccf355a9d3f366fac --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor'; +import { DVModel, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; +import { RootDvModeManager } from './RootDvModelManager'; +import matrix4 from '@ohos.matrix4' +import Log from '../../util/Log'; + +const TAG: string = "PlatformViewWrapper"; +export class PlatformViewWrapper { + private prevLeft: number; + private prevTop: number; + private left: number; + private top: number; + private bufferWidth: number; + private bufferHeight: number; + private touchProcessor: OhosTouchProcessor; + + // private onTouch = (touchEvent: TouchEvent) => { + // switch (touchEvent.type) { + // case TouchType.Down: + // this.prevLeft = this.left; + // this.prevTop = this.top; + // this.model.params.translateX = this.left; + // this.model.params.translateY = this.top; + // break; + // case TouchType.Move: + // this.model.params.translateX = this.prevLeft; + // this.model.params.translateY = this.prevTop; + // this.prevLeft = this.left; + // this.prevTop = this.top; + // break; + // case TouchType.Up: + // case TouchType.Cancel: + // default: + // break; + // } + // } + + private model : DVModel = createDVModelFromJson( new DVModelParam("Column", [])); + + public setTouchProcessor(newTouchProcessor: OhosTouchProcessor): void { + this.touchProcessor = newTouchProcessor; + } + + constructor() { + } + + public getDvModel(): DVModel { + return this.model; + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + + public setLayoutParams(parameters : DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + this.setParams(this.model.params, "marginLeft", this.getParams(parameters, "marginLeft")); + this.setParams(this.model.params, "marginTop", this.getParams(parameters, "marginTop")); + this.left = this.getParams(parameters, "marginLeft"); + this.top = this.getParams(parameters, "marginTop"); + + this.setParams(this.model.params, "width", this.getParams(parameters, "width")); + this.setParams(this.model.params, "height", this.getParams(parameters, "height")); + + // this.model.params.marginLeft = parameters.marginLeft; + // this.model.params.marginTop = parameters.marginTop; + // this.left = parameters.marginLeft; + // this.top = parameters.marginTop;; + + // this.model.params.width = parameters.width; + // this.model.params.height = parameters.height; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } +} + +class DVModelParam { + compType: string + children: [] + + constructor(compType: string, children: []) { + this.compType = compType; + this.children = children; + } +}; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..62888046c561533a3ea096c77ce7f3f634503e4c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export interface PlatformViewsAccessibilityDelegate { + /** + * Returns the root of the view hierarchy for the platform view with the requested id, or null if + * there is no corresponding view. + */ + getPlatformViewById(viewId: number): Object; + + /** Returns true if the platform view uses virtual displays. */ + usesVirtualDisplay(id: number): boolean; + + /** + * Attaches an accessibility bridge for this platform views accessibility delegate. + * + *

Accessibility events originating in platform views belonging to this delegate will be + * delegated to this accessibility bridge. + */ + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void; + + /** + * Detaches the current accessibility bridge. + * + *

Any accessibility events sent by platform views belonging to this delegate will be ignored + * until a new accessibility bridge is attached. + */ + detachAccessibilityBridge(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets new file mode 100644 index 0000000000000000000000000000000000000000..b77917fc75a9baaf6c7f88a4df6fd4349a5b789c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { PlatformViewsAccessibilityDelegate } from './PlatformViewsAccessibilityDelegate'; +import PlatformViewsChannel, { + PlatformViewBufferResized, + PlatformViewCreationRequest, + PlatformViewResizeRequest, + PlatformViewsHandler, PlatformViewTouch, PlatformViewBufferSize +} from '../../../ets/embedding/engine/systemchannels/PlatformViewsChannel'; +import PlatformView from './PlatformView'; +import { DVModel, DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import display from '@ohos.display'; +import { FlutterView } from '../../view/FlutterView'; +import { TextureRegistry } from '../../view/TextureRegistry'; +import TextInputPlugin from '../editing/TextInputPlugin'; +import { PlatformOverlayView } from './PlatformOverlayView'; +import { PlatformViewWrapper } from './PlatformViewWrapper'; +import { FlutterOverlaySurface } from '../../embedding/engine/FlutterOverlaySurface'; +import HashSet from '@ohos.util.HashSet'; +import PlatformViewRegistry from './PlatformViewRegistry'; +import PlatformViewRegistryImpl from './PlatformViewRegistryImpl'; +import DartExecutor from '../../embedding/engine/dart/DartExecutor'; +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; +import AccessibilityBridge from '../../view/AccessibilityBridge'; +import { RootDvModeManager } from './RootDvModelManager'; +import { FlutterMutatorView } from '../../embedding/engine/mutatorsstack/FlutterMutatorView'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log' +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor' +import PlatformViewFactory from './PlatformViewFactory' +import { ByteBuffer } from '../../util/ByteBuffer'; + +const TAG = "PlatformViewsController" + +export default class PlatformViewsController implements PlatformViewsAccessibilityDelegate, PlatformViewsHandler { + private registry: PlatformViewRegistryImpl; + private context: Context; + private flutterView: FlutterView; + private textureRegistry: TextureRegistry; + private textInputPlugin: TextInputPlugin; + private platformViewsChannel: PlatformViewsChannel; + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + private nextOverlayLayerId: number = 0; + private ohosTouchProcessor: OhosTouchProcessor; + private usesSoftwareRendering: boolean = false; + + private platformViews: Map; + private overlayLayerViews: Map; + private viewWrappers: Map; + private currentFrameUsedOverlayLayerIds: HashSet; + private currentFrameUsedPlatformViewIds: HashSet; + private rootDvModel = RootDvModeManager.getRootDvMode(); + private platformViewParent: Map; + + constructor() { + this.registry = new PlatformViewRegistryImpl(); + this.accessibilityEventsDelegate = new AccessibilityEventsDelegate(); + this.overlayLayerViews = new Map(); + this.currentFrameUsedOverlayLayerIds = new HashSet(); + this.currentFrameUsedPlatformViewIds = new HashSet(); + this.viewWrappers = new Map(); + this.platformViews = new Map(); + this.platformViewParent = new Map(); + } + + + getPlatformViewById(viewId: number): Object { + throw new Error('Method not implemented.'); + } + + usesVirtualDisplay(id: number): boolean { + throw new Error('Method not implemented.'); + } + + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void { + throw new Error('Method not implemented.'); + } + + detachAccessibilityBridge(): void { + throw new Error('Method not implemented.'); + } + + createForPlatformViewLayer(request: PlatformViewCreationRequest): void { + Log.i(TAG, "Enter createForPlatformViewLayer"); + this.ensureValidRequest(request); + + let platformView: PlatformView = this.createPlatformView(request, false); + + this.configureForHybridComposition(platformView, request); + } + + dispose(viewId: number): void { + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Disposing unknown platform view with id: " + viewId); + return; + } + this.platformViews.delete(viewId); + + try { + platformView.dispose(); + } catch (err) { + Log.e(TAG, "Disposing platform view threw an exception", err); + } + + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper != null) { + this.viewWrappers.delete(viewId); + } + + let parentView: FlutterMutatorView = this.platformViewParent.get(viewId); + if (parentView != null) { + this.platformViewParent.delete(viewId); + } + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void { + let physicalWidth: number = this.toPhysicalPixels(request.newLogicalWidth); + let physicalHeight: number = this.toPhysicalPixels(request.newLogicalHeight); + let viewId: number = request.viewId; + Log.i(TAG, `Resize viewId ${viewId}, pw:${physicalWidth}, ph:${physicalHeight},lw:${request.newLogicalWidth}, lh:${request.newLogicalHeight}`); + + let platformView: PlatformView = this.platformViews.get(viewId); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (platformView == null || viewWrapper == null) { + Log.e(TAG, "Resizing unknown platform view with id: " + viewId); + return; + } + + let viewWrapperLayoutParams: DVModelParameters = viewWrapper.getDvModel().getLayoutParams(); + if (physicalWidth) { + this.setParams(viewWrapperLayoutParams, "width", physicalWidth); + // viewWrapperLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(viewWrapperLayoutParams, "height", physicalHeight); + // viewWrapperLayoutParams.height = physicalHeight; + } + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView != null) { + let embeddedViewLayoutParams = embeddedView.getLayoutParams(); + if (physicalWidth) { + this.setParams(embeddedViewLayoutParams, "width", physicalWidth); + // embeddedViewLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(embeddedViewLayoutParams, "height", physicalHeight); + // embeddedViewLayoutParams.height = physicalHeight; + } + } + + onComplete.run(new PlatformViewBufferSize(request.newLogicalWidth, request.newLogicalHeight)); + } + + offset(viewId: number, top: number, left: number): void { + Log.i(TAG, `Offset is id${viewId}, t:${top}, l:${left}`); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper == null) { + Log.e(TAG, "Setting offset for an unknown platform view with id: " + viewId); + return; + } + + let physicalTop = this.toPhysicalPixels(top); + let physicalLeft = this.toPhysicalPixels(left); + let params = viewWrapper.getDvModel().params; + this.setParams(params, "marginTop", physicalTop); + this.setParams(params, "marginLeft", physicalLeft); + // params.marginTop = physicalTop; + // params.marginLeft = physicalLeft; + viewWrapper.setLayoutParams(params); + } + + onTouch(touch: PlatformViewTouch): void { + let viewId: number = touch.viewId; + let density: number = display.getDefaultDisplaySync().densityDPI; + + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Sending touch to an unknown platform view with id: " + viewId); + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + Log.e(TAG, "Sending touch to a null dv model with id: " + viewId); + } + Log.e(TAG, "Sending touch to a dv model with id: " + viewId.toString()); + sendEventByKey(viewId.toString(), 10, ""); + } + + setDirection(viewId: number, direction: number): void { + if (!this.validateDirection(direction)) { + throw new Error("Trying to set unknown direction value: " + + direction + + "(view id: " + + viewId + + ")"); + } + + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + this.setParams(embeddedView.params, "direction", direction); + // embeddedView.params.direction = direction; + } + + validateDirection(direction:number):boolean { + return direction == Direction.Ltr || direction == Direction.Rtl || direction == Direction.Auto; + } + + clearFocus(viewId: number): void { + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + focusControl.requestFocus("flutterXComponent"); + } + synchronizeToNativeViewHierarchy(yes: boolean): void { + throw new Error('Method not implemented.'); + } + + public createForTextureLayer(request: PlatformViewCreationRequest): number { + Log.i(TAG, "Enter createForTextureLayer"); + this.ensureValidRequest(request); + + let viewId: number = request.viewId; + if (this.viewWrappers.get(request.viewId) != null) { + throw new Error( + "Trying to create an already created platform view, view id: " + viewId); + } + + let platformView: PlatformView = this.createPlatformView(request, true); + let dynamicView: DVModel = platformView.getView(); + return this.configureForTextureLayerComposition(platformView, request); + } + + private ensureValidRequest(request: PlatformViewCreationRequest): void { + if (!this.validateDirection(request.direction)) { + throw new Error("Trying to create a view with unknown direction value: " + + request.direction + + "(view id: " + + request.viewId + + ")") + } + } + + private createPlatformView(request: PlatformViewCreationRequest, wrapContext: boolean): PlatformView { + Log.i(TAG, "Enter createPlatformView"); + const viewFactory: PlatformViewFactory = this.registry.getFactory(request.viewType); + if (viewFactory == null) { + throw new Error("Trying to create a platform view of unregistered type: " + request.viewType) + } + + let createParams: ESObject = null; + if (request.params != null) { + let byteParas : ByteBuffer = request.params as ByteBuffer; + createParams = viewFactory.getCreateArgsCodec().decodeMessage(byteParas.buffer); + } + + let mutableContext: common.Context = this.context; + let platformView = viewFactory.create(mutableContext, request.viewId, createParams); + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView == null) { + throw new Error("PlatformView#getView() returned null, but an dynamic view reference was expected."); + } + + this.setParams(embeddedView.params, "direction", request.direction); + // embeddedView.params.direction = request.direction; + + this.platformViews.set(request.viewId, platformView); + return platformView; + } + + // Configures the view for Hybrid Composition mode. + private configureForHybridComposition(platformView: PlatformView, request: PlatformViewCreationRequest): void { + Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId); + } + + private configureForTextureLayerComposition(platformView: PlatformView, request: PlatformViewCreationRequest): number { + Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId); + + let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); + let textureId: number = 0; + + let physicalTop: number = this.toPhysicalPixels(request.logicalTop); + let physicalLeft: number = this.toPhysicalPixels(request.logicalLeft); + + Log.i(TAG, `View pW:${request.logicalWidth}, pH:${request.logicalHeight}, pT:${physicalTop}, pL:${physicalLeft}`); + + let param: DVModelParameters = new DVModelParameters(); + + this.setParams(param, "marginLeft", physicalLeft); + this.setParams(param, "marginTop", physicalTop); + // param.marginLeft = physicalLeft; + // param.marginTop = physicalTop; + + let model = platformView.getView(); + if (request.logicalWidth != null) { + let physicalWidth: number = this.toPhysicalPixels(request.logicalWidth); + this.setParams(model.params, "width", physicalWidth); + this.setParams(param, "width", physicalWidth); + // model.params.width = physicalWidth; + // param.width = physicalWidth; + } + + if (request.logicalHeight != null) { + let physicalHeight: number = this.toPhysicalPixels(request.logicalHeight); + this.setParams(model.params, "height", physicalHeight); + this.setParams(param, "height", physicalHeight); + // model.params.height = physicalHeight; + // param.height = physicalHeight; + } + + viewWrapper.setLayoutParams(param); + viewWrapper.addDvModel(model); + + RootDvModeManager.addDvModel(viewWrapper.getDvModel()); + this.viewWrappers.set(request.viewId, viewWrapper); + Log.i(TAG, "Create platform view success"); + + return textureId; + } + + public attach(context: Context, textureRegistry: TextureRegistry, dartExecutor: DartExecutor): void { + if (this.context != null) { + + } + this.context = context; + this.textureRegistry = textureRegistry; + this.platformViewsChannel = new PlatformViewsChannel(dartExecutor); + this.platformViewsChannel.setPlatformViewsHandler(this); + } + + public detach(): void { + if (this.platformViewsChannel != null) { + this.platformViewsChannel.setPlatformViewsHandler(null); + } + this.destroyOverlaySurfaces(); + this.platformViewsChannel = null; + this.context = null; + this.textureRegistry = null; + } + + public attachToView() { + for (let wrapper of this.viewWrappers.values()) { + this.rootDvModel.model.children.push(wrapper.getDvModel()); + } + for (let mutator of this.platformViewParent.values()) { + this.rootDvModel.model.children.push(mutator.getDvModel()); + } + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewAttached(this.rootDvModel.model); + } + } + + public detachFromView(): void { + for (let index = 0; index < this.viewWrappers.size; index++) { + this.rootDvModel.model.children.pop(); + } + for (let index = 0; index < this.platformViewParent.size; index++) { + this.rootDvModel.model.children.pop(); + } + this.destroyOverlaySurfaces(); + this.removeOverlaySurfaces(); + this.rootDvModel = null; + + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewDetached(); + } + } + + public attachTextInputPlugin(textInputPlugin: TextInputPlugin): void { + this.textInputPlugin = textInputPlugin; + } + + public detachTextInputPlugin(): void { + this.textInputPlugin == null; + } + + public getRegistry(): PlatformViewRegistry { + return this.registry; + } + + public onDetachedFromNapi(): void { + this.diposeAllViews(); + } + + public onPreEngineRestart(): void { + this.diposeAllViews(); + } + + private getDisplayDensity(): number { + return display.getDefaultDisplaySync().densityPixels; + } + private toPhysicalPixels(logicalPixels: number): number { + return Math.round(px2vp(logicalPixels * this.getDisplayDensity())); + } + + private toLogicalPixelsByDensity(physicalPixels: number, displayDensity: number): number { + return Math.round(physicalPixels / displayDensity); + } + + private toLogicalPixels(physicalPixels: number): number { + return this.toLogicalPixelsByDensity(physicalPixels, this.getDisplayDensity()); + } + + + private diposeAllViews(): void { + } + + private initializeRootImageViewIfNeeded(): void { + } + + initializePlatformViewIfNeeded(viewId: number): void { + let platformView: PlatformView = this.platformViews[viewId]; + if (platformView == null) { + throw new Error("Platform view hasn't been initialized from the platform view channel."); + } + if (this.platformViewParent[viewId] == null) { + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + throw new Error("PlatformView#getView() returned null, but an ohos dv model reference was expected."); + } + let parentView: FlutterMutatorView = new FlutterMutatorView(); + parentView.setOnDescendantFocusChangeListener(() => { + this.platformViewsChannel.invokeViewFocused(viewId); + }, () => { + if (this.textInputPlugin != null) { + this.textInputPlugin.clearTextInputClient(); + } + }); + } + + public onDisplayOverlaySurface(id: number, x: number, y: number, width: number, height: number): void { + } + + public onBeginFrame(): void { + this.currentFrameUsedOverlayLayerIds.clear(); + this.currentFrameUsedPlatformViewIds.clear(); + } + + public onEndFrame(): void { + } + + private finishFrame(isFrameRenderedUsingImageReaders: boolean): void { + } + + public createOverlaySurfaceByPlatformOverlayView(imageView: PlatformOverlayView) { + let id = this.nextOverlayLayerId++; + this.overlayLayerViews.set(id, imageView); + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + public createOverlaySurface(): FlutterOverlaySurface { + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + private destroyOverlaySurfaces(): void { + } + + private removeOverlaySurfaces(): void { + if (!(this.flutterView instanceof FlutterView)) { + return; + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cc2cb0b2cc44032d2384282013785d150162bc9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DVModelContainer, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +@Component +struct XComponentStruct { + private context: ESObject; + + build() { + XComponent({ id: 'flutterXComponent', type: 'texture', libraryname: 'flutter' }) + .onLoad((context) => { + this.context = context; + }) + .onDestroy(() => { + }) + } +} + +interface $$type { + param: DVModelParameters +} + +@Builder +function BuildXComponentStruct($$: $$type) { + XComponentStruct(); +} + +class DVModelJson { + compType: string + children: Array + attributes: ESObject + + constructor(compType: string, children: Array, attributes: ESObject) { + this.compType = compType + this.children = children + this.attributes = attributes + } +} + +export class RootDvModeManager { + private static xComponentModel: ESObject = + { + compType: "xComponent", + build: BuildXComponentStruct + }; + private static model: DVModel = createDVModelFromJson(new DVModelJson("Stack", [RootDvModeManager.xComponentModel], { + alignContent: Alignment.TopStart + },) + + ); + private static container: DVModelContainer = new DVModelContainer(RootDvModeManager.model); + + public static getRootDvMode(): DVModelContainer { + return RootDvModeManager.container; + } + + public static addDvModel(model: DVModel): void { + RootDvModeManager.container.model.children.push(model); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets new file mode 100644 index 0000000000000000000000000000000000000000..99a7d4b522caa6daf09b06e6feb40bcd6203abd3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * A byte buffer. + * + * Supports the following data types: + * - Bool + * - Int (8, 16, 32, 64) + * - Uint (8, 16, 32, 64) + * - BigInt (64) + * - String (utf8, utf16, and delimited) + * - TypedArray + * + */ +export class ByteBuffer { + + /** + * Creates a byte buffer. + * @param source The data source. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns A byte buffer. + */ + static from(source: ArrayBuffer, byteOffset?: number, byteLength?: number): ByteBuffer { + // if (ArrayBuffer.isView(source)) { + // byteOffset = source.byteOffset + (byteOffset || 0) + // } + const byteBuffer = new ByteBuffer() + byteBuffer.dataView = byteLength === undefined ? new DataView(source, byteOffset) : new DataView(source, byteOffset, Math.min(source.byteLength, byteLength)) + byteBuffer.mByteOffset = byteBuffer.dataView.byteOffset + return byteBuffer + } + + /** + * The dataView. + */ + private dataView: DataView + + /** + * The byte offset. + */ + mByteOffset: number = 0 + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteOffset(): number { + return this.mByteOffset + } + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteLength(): number { + return this.dataView.byteLength + } + + /** + * The number of remaining bytes. + * @returns The number of bytes remaining. + */ + get bytesRemaining(): number { + return this.dataView.byteLength - this.mByteOffset + } + + hasRemaining(): boolean { + return this.mByteOffset < this.dataView.byteLength; + } + + get buffer(): ArrayBuffer { + const dataBuffer = new DataView(new ArrayBuffer(this.mByteOffset)); + for (let i = 0; i < this.mByteOffset; i++) { + dataBuffer.setUint8(i, this.dataView.getUint8(i)); + } + return dataBuffer.buffer + } + + /** + * Skips the byte offset. + * @param byteLength The byte length. + */ + skip(byteLength: number): void { + this.mByteOffset += byteLength + } + + /** + * Resets the byte offset. + */ + reset(): void { + this.mByteOffset = this.dataView.byteOffset + } + + /** + * Clears the byte buffer. + */ + clear(): void { + this.getUint8Array(0).fill(0) + } + + /** + * check buffer capacity. + */ + checkWriteCapacity(slen: number): void { + if (this.mByteOffset + slen > this.dataView.byteLength) { + let checkBuffer = new DataView(new ArrayBuffer(this.dataView.byteLength + slen + 512)); + for (let i = 0; i < this.mByteOffset; i++) { + checkBuffer.setUint8(i, this.dataView.getUint8(i)); + } + this.dataView = checkBuffer; + } + } + + /** + * Gets a boolean. + * @param byteOffset The byte offset. + */ + getBool(byteOffset: number): boolean { + return this.getInt8(byteOffset) !== 0 + } + + /** + * Reads the next boolean. + */ + readBool(): boolean { + return this.getInt8(this.mByteOffset++) !== 0 + } + + /** + * Sets a boolean. + * @param byteOffset The byte offset. + * @param value The value. + */ + setBool(byteOffset: number, value: boolean): void { + this.dataView.setInt8(byteOffset, value ? 1 : 0) + } + + /** + * Writes the next boolean. + * @param value The value. + */ + writeBool(value: boolean): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value ? 1 : 0) + } + + /** + * Gets an signed byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getInt8(byteOffset: number): number { + return this.dataView.getInt8(byteOffset) + } + + /** + * Reads the next signed byte. + * @returns The value. + */ + readInt8(): number { + return this.getInt8(this.mByteOffset++) + } + + /** + * Sets a signed byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setInt8(byteOffset: number, value: number): void { + this.dataView.setInt8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeInt8(value: number): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value) + } + + /** + * Gets an unsigned byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getUint8(byteOffset: number): number { + return this.dataView.getUint8(byteOffset) + } + + /** + * Reads the next unsigned byte. + * @returns The value. + */ + readUint8(): number { + return this.getUint8(this.mByteOffset++) + } + + /** + * Sets an unsigned byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8(byteOffset: number, value: number): void { + this.dataView.setUint8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeUint8(value: number): void { + this.checkWriteCapacity(1) + this.setUint8(this.mByteOffset++, value) + } + + /** + * Gets an signed short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt16(byteOffset, littleEndian) + } + + /** + * Reads the next signed short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt16(littleEndian?: boolean): number { + const value = this.getInt16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets a signed short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setInt16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an unsigned short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint16(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint16(littleEndian?: boolean): number { + const value = this.getUint16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets an unsigned short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setUint16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an signed integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt32(byteOffset, littleEndian) + } + + /** + * Reads the next signed integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt32(littleEndian?: boolean): number { + const value = this.getInt32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a signed integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setInt32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets an unsigned integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint32(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint32(littleEndian?: boolean): number { + const value = this.getUint32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets an unsigned integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setUint32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a float. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat32(byteOffset, littleEndian) + } + + /** + * Reads the next float. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat32(littleEndian?: boolean): number { + const value = this.getFloat32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a float. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat32(byteOffset, value, littleEndian) + } + + /** + * Writes the next float. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setFloat32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a double. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat64(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat64(byteOffset, littleEndian) + } + + /** + * Reads the next double. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat64(littleEndian?: boolean): number { + const value = this.getFloat64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a double. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat64(byteOffset, value, littleEndian) + } + + /** + * Writes the next double. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setFloat64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigInt64(byteOffset, littleEndian) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigInt64(littleEndian?: boolean): bigint { + const value = this.getBigInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigInt64(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigInt64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigUint64(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigUint64(littleEndian?: boolean): bigint { + const value = this.getBigUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigUint64(byteOffset, value, littleEndian) + } + + /** + * Writes the next unsigned long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigUint64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigInt64(byteOffset, littleEndian)) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt64(littleEndian?: boolean): number { + const value = this.getInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigInt64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigUint64(byteOffset, littleEndian)) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint64(littleEndian?: boolean): number { + const value = this.getUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigUint64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { + return new Uint8Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned bytes. + * @param byteLength The byte length. + * @returns The value. + */ + readUint8Array(byteLength?: number): Uint8Array { + const value = this.getUint8Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8Array(byteOffset: number, value: Uint8Array): void { + const byteLength = value.byteLength + this.getUint8Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint8Array(value: Uint8Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint8Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets an array of unsigned shorts. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { + if (byteLength !== undefined) { + byteLength = Math.floor(byteLength / 2) + } + return new Uint16Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned shorts. + * @param byteLength The byte length. + * @returns The value. + */ + readUint16Array(byteLength?: number): Uint16Array { + const value = this.getUint16Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint16Array(byteOffset: number, value: Uint16Array): void { + const byteLength = value.byteLength + this.getUint16Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint16Array(value: Uint16Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint16Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets a string. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { + const decoder = new util.TextDecoder(byteEncoding || "utf-8") + const encoded = this.getUint8Array(byteOffset, byteLength) + return decoder.decode(encoded) + } + + /** + * Reads the next string. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + readString(byteLength?: number, byteEncoding?: string): string { + const value = this.getString(this.mByteOffset, byteLength, byteEncoding) + if (byteLength === undefined) { + this.mByteOffset = this.dataView.byteLength + } else { + this.mByteOffset += byteLength + } + return value + } + + /** + * Sets a string. + * @param byteOffset The byte offset. + * @param value The string. + * @param byteEncoding The byte encoding. + * @returns The byte length. + */ + setString(byteOffset: number, value: string, byteEncoding?: string, write?: boolean): number { + if (byteEncoding && byteEncoding !== "utf-8") { + throw new TypeError("String encoding '" + byteEncoding + "' is not supported") + } + const encoder = new util.TextEncoder() + const byteLength = Math.min(this.dataView.byteLength - byteOffset, value.length * 4) + if (write) { + this.checkWriteCapacity(byteLength) + } + const destination = this.getUint8Array(byteOffset, byteLength) + const written = encoder.encodeInto(value, destination).written + return written || 0 + } + + /** + * Writes the next a string. + * @param value The string. + * @param byteEncoding The byte encoding. + */ + writeString(value: string, byteEncoding?: string): void { + const byteLength = this.setString(this.mByteOffset, value, byteEncoding, true) + this.mByteOffset += byteLength + } + + /** + * Formats to a string. + * @param format The string format. + * @returns The string. + */ + toString(format?: string): string { + return [...this.getUint8Array(0)].map((byte: number) => { + switch(format) { + case "hex": + return ("00" + byte.toString(16)).slice(-2) + default: + return byte.toString(10) + } + }).join(" ") + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets new file mode 100644 index 0000000000000000000000000000000000000000..437b52f18049b9ba77e47350033482a06368c5c4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HiLog from '@ohos.hilog'; + +const DOMAIN: number = 0x00FF; +const TAG = "Flutter"; +const SYMBOL = " --> "; +// const FILTER_KEYS = [ +// new RegExp('hide', "gi") +// ] + +// export function filterKey(target: any, propKey: string, descriptor: PropertyDescriptor) { +// const original = descriptor.value; +// descriptor.value = function (...args: string[]) { +// let filterResult = args.map((str) => { +// let tempStr = str +// FILTER_KEYS.forEach((filterKey) => tempStr = tempStr.replace(filterKey, "**")) +// return tempStr +// }); +// const result = original.call(this, ...filterResult); +// return result; +// }; +// } + +/** + * Basic log class + */ +export default class Log { + /** + * Outputs debug-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static d(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.DEBUG)) { + HiLog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs info-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static i(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.INFO)) { + HiLog.info(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs warning-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static w(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.WARN)) { + HiLog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs error-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static e(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.ERROR)) { + HiLog.error(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs fatal-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static f(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.FATAL)) { + HiLog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Checks whether logs of the specified tag, and level can be printed. + * + * @param tag Identifies the log tag. + * @param level log level + * @since 7 + */ + private static isLoggable(level: HiLog.LogLevel): boolean { + return HiLog.isLoggable(DOMAIN, TAG, level); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..1899f74069a24a3e250378b11ac1c9492f03b8f3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../plugin/common/BinaryMessenger'; +import StringUtils from './StringUtils'; + +export default class MessageChannelUtils { + static resizeChannelBuffer(messenger: BinaryMessenger, channel: string, newSize: number) { + const dataStr = `resize\r${channel}\r${newSize}` + messenger.send(BasicMessageChannel.CHANNEL_BUFFERS_CHANNEL, StringUtils.stringToArrayBuffer(dataStr)); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..691ea0f360b40adb266bde566c2f66292a2aa0ff --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import common from '@ohos.app.ability.common'; +import fs from '@ohos.file.fs'; +import Log from './Log'; + +/** + * ohos路径获取工具 + */ +const TAG: string = "PathUtils"; + +export default class PathUtils { + static getFilesDir(context: common.Context): string { + return context.filesDir; + } + + static getCacheDirectory(context: common.Context): string { + return context.cacheDir; + } + + static getDataDirectory(context: common.Context): string { + const name = "flutter"; + const flutterDir = context.filesDir + "/" + name; + if (!fs.accessSync(flutterDir)) { + try { + fs.mkdirSync(flutterDir); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + return null; + } + } + return flutterDir; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeb7c554c30b5d3625851afc214dda8d31da9917 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * 默认字符串工具 + */ +export default class StringUtils { + static stringToArrayBuffer(str: string): ArrayBuffer { + let textEncoder = new util.TextEncoder("utf-8"); + return textEncoder.encodeInto(str).buffer; + } + + static arrayBufferToString(buffer: ArrayBuffer): string { + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true }) + return textDecoder.decode(new Uint8Array(buffer)) + } + + static isNotEmpty(str: string): boolean { + return str && str.length > 0; + } + + static isEmpty(str: string): boolean { + return (!str) || str.length == 0; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3879f4a40ea307f7491a4808ad3b816cc98b13e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class ToolUtils { + static isObj(object: Object): boolean { + return object && typeof (object) == 'object'; + } + + static implementsInterface(obj: ESObject, method: string): boolean { + return Reflect.has(obj, method) && typeof obj[method] === 'function' + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets new file mode 100644 index 0000000000000000000000000000000000000000..3caaadea7aa0cb84be3542be9c4595139cd25af4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hiTraceMeter from '@ohos.hiTraceMeter' + +export class TraceSection { + + static taskId: number = 1; + + private static cropSectionName(sectionName: string): string { + return sectionName.length < 124 ? sectionName : sectionName.substring(0, 124) + "..."; + } + + /** + * Wraps Trace.beginSection to ensure that the line length stays below 127 code units. + * + * @param sectionName The string to display as the section name in the trace. + */ + public static begin(sectionName: string): void { + hiTraceMeter.startTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId++); + } + + /** Wraps Trace.endSection. */ + public static end(sectionName: string): void { + hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e08f41fe9171658365b4e2c806b075807ddc423 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class AccessibilityBridge { + constructor(){ + + } +} + +export enum Action { + TAP = 1 << 0, + LONG_PRESS = 1 << 1, + SCROLL_LEFT = 1 << 2, + SCROLL_RIGHT = 1 << 3, + SCROLL_UP = 1 << 4, + SCROLL_DOWN = 1 << 5, + INCREASE = 1 << 6, + DECREASE = 1 << 7, + SHOW_ON_SCREEN = 1 << 8, + MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 << 9, + MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 << 10, + SET_SELECTION = 1 << 11, + COPY = 1 << 12, + CUT = 1 << 13, + PASTE = 1 << 14, + DID_GAIN_ACCESSIBILITY_FOCUS = 1 << 15, + DID_LOSE_ACCESSIBILITY_FOCUS = 1 << 16, + CUSTOM_ACTION = 1 << 17, + DISMISS = 1 << 18, + MOVE_CURSOR_FORWARD_BY_WORD = 1 << 19, + MOVE_CURSOR_BACKWARD_BY_WORD = 1 << 20, + SET_NEXT = 1 << 21, +}; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets new file mode 100644 index 0000000000000000000000000000000000000000..f95a9c04a7a44a99505b9882ba1291e7bfcb1604 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import matrix4 from '@ohos.matrix4'; + +/** + * Dynamic View creation + * from a recursive data structure + * + * exported @Component: DynamicView + * exported view model classes: + * - DVModelContainer + * - DVModel + * - DVModelParameters + * - DVModelEvents + * - DVModelChildren + * + * The purpose of exporting the DVModel classes + * is to make them available to the converter from + * JD's XML format and the expression parser. These + * components are expected to generate and update the + * DVModel. + * + * An application written by JS should only import + * DynamicView, DVModelContainer to be used in their own ArkUI + * container view. + */ + +/** + * View Model classes + */ + +@Observed +export class DVModelParameters extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelEvents extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelChildren extends Array { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +let nextId: number = 1; + +@Observed +export class DVModel { + id_: number; + compType: string; + params: DVModelParameters; + events: DVModelEvents; + children: DVModelChildren; + builder: ESObject; + + constructor(compType: string, params: DVModelParameters, events: DVModelEvents, children: DVModelChildren, builder?: ESObject) { + this.id_ = nextId++; + this.compType = compType; + this.params = params ?? new DVModelParameters; + this.events = events; + this.children = children; + this.builder = builder; + } + + public getLayoutParams(): DVModelParameters { + return this.params; + } +} + +// includes the root DVModel objects. +export class DVModelContainer { + model: DVModel; + + constructor(model: DVModel) { + this.model = model; + } +} + +/** + DynamicView is the @Component that does all the work: + + The following 4 features are the key solution elements for dynamic View + construction and update: + + 1. The if statement decides which framework component to create. + We can not use a factory function here, because that would requite calling + a regular function inside build() or a @Builder function. + + 2. Take note of the @Builder for Row, Column containers: + These functions create DynamicView Views inside a DynamicView + view. This behaviour is why we talk about DynamicView as a 'recursive' View. + All @Builder functions are member functions of the DynamicView @Component to + retain access ('this.xyz') to its decorated state variables. + + 3. The @Extend functions execute attribute and event handler registration functions + for all attributes and events permissable on the framework component, irrespective + if DVModelParameters or DVModelEvents objects includes a value or not. If not + the attribute or event is set to 'undefined' by intention. This is required to unset + any previously set value. + + 4. The scope ('this') of any lambda registered as an event hander function, e.g. for onClick, + is the @Component, in which the DVModel object is initialized. This said, it is advised to initialize + the DVModel object in the @Component that is parent to outmost DynamicView. Thereby, + any event handler function is able to mutate decorated state variables of that @Component + + */ + +@Component +export struct DynamicView { + @ObjectLink model: DVModel; + @ObjectLink children: DVModelChildren; + @ObjectLink params: DVModelParameters; + @ObjectLink events: DVModelEvents; + @BuilderParam customBuilder?: ($$: BuilderParams) => void; + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + getEvents: (events: DVModelEvents, element: string) => ESObject = (events: DVModelEvents, element: string): ESObject => { + let events2 = events as Record; + return events2.element; + } + + /* + we use this @Styles member function to set all common attributes and event handlers + and set component specific attribute and event handler functions in the @Builder function + */ + @Styles + common_attrs() { + // let params2 = this.params as Record | matrix4.Matrix4Transit>; + // .width(this.params["width"]) + // .height(this.params["height"]) + // .backgroundColor(this.params["backgroundColor"]) + // .onClick(this.events["onClick"]) + // .margin({ + // left: this.params["marginLeft"], + // right: this.params["marginRight"], + // top: this.params["marginTop"], + // bottom: this.params["marginBottom"] + // }) + // .onTouch(this.events["onTouch"]) + // .onFocus(this.events['onFocus']) + // .onBlur(this.events["onBlur"]) + // .translate({ + // x: this.params["translateX"], + // y: this.params["translateY"], + // z: this.params["translateZ"] + // }) + // .transform(this.params["matrix"]) + // .direction(this.params["direction"])this.getParams(this.params, "") + .width(this.getParams(this.params, "width")) + .height(this.getParams(this.params, "height")) + .backgroundColor(this.getParams(this.params, "backgroundColor")) + .onClick(this.getEvents(this.events, "onClick")) + .margin({ + left: this.getParams(this.params, "marginLeft"), + right: this.getParams(this.params, "marginRight"), + top: this.getParams(this.params, "marginTop"), + bottom: this.getParams(this.params, "marginBottom") + }) + .onTouch(this.getEvents(this.events, "onTouch")) + .onFocus(this.getEvents(this.events, "onFocus")) + .onBlur(this.getEvents(this.events, "onBlur")) + .translate({ + x: this.getParams(this.params, "translateX"), + y: this.getParams(this.params, "translateY"), + z: this.getParams(this.params, "translateZ") + }) + .transform(this.getParams(this.params, "matrix")) + .direction(this.getParams(this.params, "direction")) + } + + @Styles + clip_attrs() { + .clip(this.getParams(this.params, "rectWidth") ? new Rect({ + width: this.getParams(this.params, "rectWidth"), + height: this.getParams(this.params, "rectHeight"), + radius: this.getParams(this.params, "rectRadius") + }) : null) + .clip(this.getParams(this.params, "pathWidth") ? new Path({ + width: this.getParams(this.params, "pathWidth"), + height: this.getParams(this.params, "pathHeight"), + commands: this.getParams(this.params, "pathCommands") + }) : null) + } + + @Builder + buildChildren() { + ForEach(this.children, + (child: ESObject) => { + DynamicView({ + model: child as DVModel, + params: child.params, + events: child.events, + children: child.children, + customBuilder: child.builder + }) + }, + (child: ESObject) => `${child.id_}` + ) + } + + @Builder + buildRow() { + Row() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildColumn() { + Column() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildStack() { + Stack() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + .alignContent(this.getParams(this.params, "alignContent")) + } + + @Builder + buildText() { + Text(`${this.getParams(this.params, "value")}`) + .common_attrs() + .fontColor(this.getParams(this.params, "fontColor")) + } + + @Builder + buildImage() { + Image(this.getParams(this.params, "src")) + .common_attrs() + } + + // Button with label + @Builder + buildButton() { + Button(this.getParams(this.params, "value")) + .common_attrs() + } + + @Builder + buildCustom() { + if (this.customBuilder) { + this.customBuilder(new BuilderParams(this.params)); + } + } + + build() { + if (this.model.compType == "Column") { + this.buildColumn() + } else if (this.model.compType == "Row") { + this.buildRow() + } else if (this.model.compType == "Stack") { + this.buildStack() + } else if (this.model.compType == "Text") { + this.buildText() + } else if (this.model.compType == "Image") { + this.buildImage() + } else if (this.model.compType == "Button") { + this.buildButton() + } else { + this.buildCustom() + } + } +} + +export class BuilderParams { + params: DVModelParameters; + + constructor(params: DVModelParameters) { + this.params = params; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b97e5e5092748f7bc9e0f3af7482921891baf0f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DVModel, DVModelParameters, DVModelEvents, DVModelChildren } from "./dynamicView"; + +export function createDVModelFromJson(json: Object): DVModel { + + /* private use helper functions */ + let createChildrenFrom: (children: Array) => DVModelChildren = (children: Array): DVModelChildren => { + let result = new DVModelChildren(); + if (Array.isArray(children)) { + (children as Array).forEach(child => { + const childView = createDVModelFromJson(child); + if (childView != undefined) { + result.push(childView); + } + }); + } + return result; + } + + let setParams: (result: DVModelParameters | DVModelEvents, key: ESObject, element: Object ) => void = (result: DVModelParameters, key: ESObject, element: ESObject): void => { + let newResult = result as Record; + newResult.key = element.key; + } + + let createAttributesFrom: (attributes: Object) => DVModelParameters = (attributes: Object): DVModelParameters => { + let result = new DVModelParameters(); + if ((typeof attributes == "object") && (!Array.isArray(attributes))) { + Object.keys(attributes).forEach(k => {setParams(result, k, attributes)}); + } + return result; + } + + let createEventsFrom: (events: Object) => DVModelEvents = (events: Object): DVModelEvents => { + let result = new DVModelEvents(); + if ((typeof events == "object") && (!Array.isArray(events))) { + Object.keys(events).forEach(k => {setParams(result, k, events)}); + } + return result; + } + + if (typeof json !== 'object') { + console.error("createDVModelFromJson: input is not JSON"); + return undefined; + } + + let jsonObject = json as Record; + return new DVModel( + jsonObject.compType, + createAttributesFrom(jsonObject["attributes"]), + createEventsFrom(jsonObject["events"]), + createChildrenFrom(jsonObject["children"]), + jsonObject["build"] + ); +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..f52152001a497e70586215af090b2a81190e1187 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from '../embedding/engine/FlutterNapi'; + +export class FlutterCallbackInformation { + callbackName: string; + callbackClassName: string; + callbackLibraryPath: string; + + /** + * Get callback information for a given handle. + * + * @param handle the handle for the callback, generated by `PluginUtilities.getCallbackHandle` in + * `dart:ui`. + * @return an instance of FlutterCallbackInformation for the provided handle. + */ + static lookupCallbackInformation(handle: number): FlutterCallbackInformation { + return FlutterNapi.nativeLookupCallbackInformation(handle); + } + + constructor(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { + this.callbackName = callbackName; + this.callbackClassName = callbackClassName; + this.callbackLibraryPath = callbackLibraryPath; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets new file mode 100644 index 0000000000000000000000000000000000000000..6cc452fb32b855832651463166ae1a7f8cf5f0d4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets @@ -0,0 +1,122 @@ +import common from '@ohos.app.ability.common'; +import DartExecutor from '../embedding/engine/dart/DartExecutor'; +import { EngineLifecycleListener } from '../embedding/engine/FlutterEngine'; +import FlutterNapi from '../embedding/engine/FlutterNapi'; +import Log from '../util/Log'; +import FlutterPluginRegistry from '../app/FlutterPluginRegistry'; +import FlutterRunArguments from './FlutterRunArguments'; +import { FlutterView } from './FlutterView'; + +const TAG: string = "FlutterNativeView"; + +export default class FlutterNativeView { + private mContext: common.Context; + private mPluginRegistry: FlutterPluginRegistry; + private mFlutterNapi: FlutterNapi; + private dartExecutor: DartExecutor; + private mFlutterView: FlutterView; + private applicationIsRunning: boolean; + + constructor(context: common.Context, isBackgroundView?: boolean) { + if (isBackgroundView) { + Log.i(TAG, "isBackgroundView is no longer supported and will be ignored"); + } + this.mContext = context; + this.mPluginRegistry = new FlutterPluginRegistry(); + this.mFlutterNapi = new FlutterNapi(); + //this.mFlutterNapi.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.dartExecutor = new DartExecutor(this.mFlutterNapi, this.mContext.resourceManager); + this.mFlutterNapi.addEngineLifecycleListener(new EngineLifecycleListenerImpl(this.mFlutterView, this.mPluginRegistry)); + this.attach(this.mFlutterNapi, this.dartExecutor); + this.assertAttached(this.mFlutterNapi); + } + + attach(flutterNapi: FlutterNapi, dartExecutor: DartExecutor): void { + flutterNapi.attachToNative(); + dartExecutor.onAttachedToNAPI(); + } + + assertAttached(flutterNapi: FlutterNapi): void { + if (!this.isAttached(flutterNapi)) { + throw new Error('Platform View is not attached'); + } + } + + isAttached(flutterNapi: FlutterNapi): boolean { + return flutterNapi.isAttached(); + } + + detachFromFlutterView(): void { + this.mPluginRegistry.detach(); + this.mFlutterView = null; + } + + destroy(): void { + this.mPluginRegistry.destroy(); + this.dartExecutor.onDetachedFromNAPI(); + this.mFlutterView = null; + //this.mFlutterNapi.removeIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.applicationIsRunning = false; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor; + } + + getPluginRegistry(): FlutterPluginRegistry { + return this.mPluginRegistry; + } + + attachViewAndAbility(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mPluginRegistry.attach(flutterView, context); + } + + runFromBundle(args: FlutterRunArguments): void { + if (args.entrypoint == null) { + throw new Error("an entrypoint must be specific"); + } + this.assertAttached(this.mFlutterNapi); + if (this.applicationIsRunning) { + throw new Error("this flutter engine instance is already running an application"); + } + this.mFlutterNapi.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.resourceManager, null); + this.applicationIsRunning = true; + } + + isApplicationRunning(): boolean { + return this.applicationIsRunning; + } + + // getObservatoryUri(): string { + // return this.mFlutterNapi.getObservatoryUri(); + // } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private flutterView: FlutterView; + private pluginRegistry: FlutterPluginRegistry; + + onPreEngineRestart(): void { + if (this.flutterView != null) { + //this.flutterView.resetAccessibilityTree(); + } + + if (this.pluginRegistry == null) { + return; + } + + this.pluginRegistry.onPreEngineRestart(); + } + + onEngineWillDestroy(): void { + + } + + constructor(flutterView: FlutterView, pluginRegistry: FlutterPluginRegistry) { + this.flutterView = flutterView; + this.pluginRegistry = pluginRegistry; + } +} + + diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets new file mode 100644 index 0000000000000000000000000000000000000000..6354ecc36f87206b30a3a247612e103559356137 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets @@ -0,0 +1,5 @@ +export default class FlutterRunArguments { + public bundlePath: string; + public entrypoint: string; + public libraryPath: string; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets new file mode 100644 index 0000000000000000000000000000000000000000..6f940a6c57576a7123b70531b0880f6ba31d29e2 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets @@ -0,0 +1,3 @@ +export class FlutterView { + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..0b73c7401b711eb78028ae6f91ae3e5e40d2a418 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets @@ -0,0 +1,22 @@ + +export interface TextureRegistry { + + createSurfaceTexture(): SurfaceTextureEntry; + registerSurfaceTexture(): SurfaceTextureEntry; + + onTrimMemory(level: number) : void; +} + +interface SurfaceTextureEntry { + id(): number; + + release(): void; +} + +interface OnFrameConsumedListener { + onFrameConsumed(): void; +} + +interface OnTrimMemoryListener { + onTrimMemory(level: number) : void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..7fa2db04597c775a12de37f1581fec38009a0127 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/.ohpm/@ohos+flutter_ohos@file+libs+flutter_ohos.har/oh_modules/@ohos/flutter_ohos/src/main/module.json @@ -0,0 +1,20 @@ +{ + "app": { + "bundleName": "net.openvalley.helloworld", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "flutter_embedding", + "type": "har", + "deviceTypes": [ + "default" + ] + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt new file mode 100644 index 0000000000000000000000000000000000000000..d159750ecea7bec636e067dea44f6b469601d685 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/ResourceTable.txt @@ -0,0 +1 @@ +string page_show 0x02000000 \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..95e376706d75437dce67c79dfd886e97fa82f276 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/build-profile.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": "stageMode", + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + } + ], +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..eb1f1d089d8fbdcd5ea7af33ecb70f3c8b5bdfce --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { harTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets new file mode 100644 index 0000000000000000000000000000000000000000..3c96b70703b57d3e53a171aabf07727db248e94b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/index.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export { FlutterAbility } from './src/main/ets/embedding/ohos/FlutterAbility' + +export { FlutterPage } from './src/main/ets/embedding/ohos/FlutterPage' diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..c4acdada0ca16f1a1a4ada0bda0b669a04062911 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "Apache-2.0", + "devDependencies": { + "@types/libflutter.so": "file:./src/main/cpp/types/libflutter" + }, + "author": "", + "name": "flutter_embedding", + "description": "Please describe the basic information.", + "main": "index.ets", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..67f95808136a13ece2a5946e0aa6ff97e2a5eadb --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index.d.ts @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import image from '@ohos.multimedia.image'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; + +export const getContext: (a: number) => napiContext; + +export class napiContext { + onPageShow(); + + onPageHide(); +} + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => {}; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + +export const nativeAttach: (napi: FlutterNapi) => number; + +export const nativeRunBundleAndSnapshotFromLibrary: ( + nativeShellHolderId: number, + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +//Send a data-carrying response to a platform message received from Dart. +export const nativeInvokePlatformMessageResponseCallback: (nativeShellHolderId: number, responseId: number, message: ArrayBuffer, position: number) => void; + +// Send an empty response to a platform message received from Dart. +export const nativeInvokePlatformMessageEmptyResponseCallback: (nativeShellHolderId: number, responseId: number) => void; + +// Send a data-carrying platform message to Dart. +export const nativeDispatchPlatformMessage: (nativeShellHolderId: number, channel: String, message: ArrayBuffer, position: number, responseId: number) => void; + +// Send an empty platform message to Dart. +export const nativeDispatchEmptyPlatformMessage: (nativeShellHolderId: number, channel: String, responseId: number) => void; + +export const nativeSetViewportMetrics: (nativeShellHolderId: number, devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array) => void; + +export const nativeImageDecodeCallback: (width: number, height: number, imageGeneratorPointer: number, pixelMap : image.PixelMap) => void; + +export const nativeGetSystemLanguages: (nativeShellHolderId: number, languages: Array) => void; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts new file mode 100644 index 0000000000000000000000000000000000000000..f74af44a9d9f5796d76516723d45ec0a8791a76b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/index_actual.d.ts @@ -0,0 +1,267 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from '../../../ets/embedding/engine/FlutterNapi'; +import image from '@ohos.multimedia.image'; + +/** + * 设置刷新率 + */ +export const nativeUpdateRefreshRate: ( + ate: number +) => void; + +/** + * 初始化dart vm和flutter engine + */ +export const nativeInit: ( + context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number +) => void; + + +/** + * 加载dart工程构建产物 + */ +export const nativeRunBundleAndSnapshotFromLibrary: ( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array +) => void; + +/** + * 初始化SkFontMgr::RefDefault(),skia引擎文字管理初始化 + */ +export const nativePrefetchDefaultFontManager: () => void; + +/** + * 返回是否支持软件绘制 + */ +export const nativeGetIsSoftwareRenderingEnabled: () => boolean; + +/** + * attach flutterNapi实例给到 native engine,这个支持rkts到flutter平台的无关引擎之间的通信。 + * attach只需要执行一次 + */ +export const nativeAttach: (flutterNapi: FlutterNapi) => number; + +/** + * 从当前的flutterNapi复制一个新的实例 + */ +export const nativeSpawn: ( + nativeSpawningShellId: number, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + initialRoute: string, + entrypointArgs: Array +) => FlutterNapi; + +/** + * Detaches flutterNapi和engine之间的关联 + * 这个方法执行前提是flutterNapi已经和engine关联 + */ +export const nativeDestroy: ( + nativeShellHolderId: number +) => void; + +// 不需要实现,未使用到 +// export const nativeImageHeaderCallback: ( +// imageGeneratorPointer: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceCreated: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceWindowChanged: ( +// nativeShellHolderId: number +// ) => void; + + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceChanged: ( +// nativeShellHolderId: number, +// width: number, +// height: number +// ) => void; + +/** + * 不需要实现,c++层已有nativeSurface回调 + */ +// export const nativeSurfaceDestroyed: ( +// nativeShellHolderId: number +// ) => void; + +/** + * 把物理屏幕参数通知到native + */ +export const nativeSetViewportMetrics: ( + nativeShellHolderId: number, + devicePixelRatio: number, + physicalWidth: number, + physicalHeight: number, + physicalPaddingTop: number, + physicalPaddingRight: number, + physicalPaddingBottom: number, + physicalPaddingLeft: number, + physicalViewInsetTop: number, + physicalViewInsetRight: number, + physicalViewInsetBottom: number, + physicalViewInsetLeft: number, + systemGestureInsetTop: number, + systemGestureInsetRight: number, + systemGestureInsetBottom: number, + systemGestureInsetLeft: number, + physicalTouchSlop: number, + displayFeaturesBounds: Array, + displayFeaturesType: Array, + displayFeaturesState: Array +) => void; + +/** + * 设置能力参数 + */ +export const nativeSetAccessibilityFeatures: ( + nativeShellHolderId: number, + flags: number +) => void; + +/** + * 清除某个messageData + */ +export const nativeCleanupMessageData: ( + messageData: number +) => void; + +/** + * 发送一个空的PlatformMessage + */ +export const nativeDispatchEmptyPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + responseId: number +) => void; + +/** + * 发送一个PlatformMessage + */ +export const nativeDispatchPlatformMessage: ( + nativeShellHolderId: number, + channel: string, + message: ArrayBuffer, + position: number, + responseId: number +) => void; + +/** + * 空的PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageEmptyResponseCallback: ( + nativeShellHolderId: number, + responseId: number +) => void; + +/** + * PlatformMessage响应回调 + */ +export const nativeInvokePlatformMessageResponseCallback: ( + nativeShellHolderId: number, + responseId: number, + message: ArrayBuffer, + position: number +) => void; + + +/** + * load一个合法的.so文件到dart vm + */ +export const nativeLoadDartDeferredLibrary: ( + nativeShellHolderId: number, + loadingUnitId: number, + searchPaths: Array +) => void; + +/** + * 设置ResourceManager和assetBundlePath到engine + */ +export const nativeUpdateOhosAssetManager: ( + nativeShellHolderId: number, + resourceManager: resourceManager.ResourceManager, + assetBundlePath: string +) => void; + +/** + * 加载动态库,或者dart库失败时的通知 + */ +export const nativeDeferredComponentInstallFailure: ( + loadingUnitId: number, + error: string, + isTransient: boolean +) => void; + +/** + * 从engine获取当前绘制pixelMap + */ +export const nativeGetPixelMap: () => image.PixelMap; + +/** + * 应用低内存警告 + */ +export const nativeNotifyLowMemoryWarning: ( + nativeShellHolderId: number +) => void; + +// ----- Start FlutterTextUtils Methods ---- +/** + * 下面的方法,从键盘输入中判断当前字符是否是emoji,实现优先级低 + */ +export const nativeFlutterTextUtilsIsEmoji: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifier: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsEmojiModifierBase: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsVariationSelector: ( + codePoint: number +) => boolean; + +export const nativeFlutterTextUtilsIsRegionalIndicator: ( + codePoint: number +) => boolean; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..216ed0d7205d22e5524249550749945324d041bc --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/cpp/types/libflutter/oh-package.json5 @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "name": "libflutter.so", + "types": "./index.d.ts", + "version": "", + "description": "Please describe the basic information." +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets new file mode 100644 index 0000000000000000000000000000000000000000..4e6f2f8b0e5dd765611d87ac3b2c2c552ff5adb2 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/FlutterInjector.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from './embedding/engine/FlutterNapi'; +import FlutterLoader from './embedding/engine/loader/FlutterLoader'; + +/** + * flutter相关主要类的单例持有,帮助实现自身和其他类的实例化管理 + */ +export default class FlutterInjector { + private static instance: FlutterInjector; + + private flutterLoader: FlutterLoader; + private flutterNapi: FlutterNapi; + + static getInstance(): FlutterInjector { + if (FlutterInjector.instance == null) { + FlutterInjector.instance = new FlutterInjector(); + } + return FlutterInjector.instance; + } + /** + * 初始化 + */ + private constructor() { + this.flutterNapi = new FlutterNapi(); + this.flutterLoader = new FlutterLoader(this.flutterNapi); + } + + getFlutterLoader(): FlutterLoader { + return this.flutterLoader; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..760659f83d18913991151d7c1bc51bcb0f6fd50e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/app/FlutterPluginRegistry.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterView from '../embedding/ohos/FlutterView'; +import common from '@ohos.app.ability.common'; +import PlatformViewController from '../plugin/platform/PlatformViewsController' +import Log from '../util/Log'; + +export default class FlutterPluginRegistry { + private mPlatformViewsController: PlatformViewController; + private mFlutterView: FlutterView; + private mContext: common.Context; + + constructor() { + this.mPlatformViewsController = new PlatformViewController(); + } + + attach(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mContext = context; + } + + detach(): void { + this.mPlatformViewsController.detach(); + this.mPlatformViewsController.onDetachedFromNapi(); + this.mFlutterView = null; + this.mContext = null; + } + + destroy(): void { + this.mPlatformViewsController.onDetachedFromNapi(); + } + + onPreEngineRestart(): void{ + this.mPlatformViewsController.onPreEngineRestart(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..07497e672b21c51727c1a45166504e19603e4063 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/component/FlutterComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * 基础component,还未封装,看情况是否使用 + */ +@Component +export default struct FlutterComponent { + build() { + Row() { + Column() { + Text("xxx") + .fontSize(50) + .fontWeight(FontWeight.Bold) + } + .width('100%') + } + .height('100%') + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets new file mode 100644 index 0000000000000000000000000000000000000000..4a16a419d9c7a5df84379278cdc7fb113624d7f7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine.ets @@ -0,0 +1,277 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LifecycleChannel from './systemchannels/LifecycleChannel'; +import DartExecutor, { DartEntrypoint } from './dart/DartExecutor'; +import FlutterShellArgs from './FlutterShellArgs'; +import FlutterInjector from '../../FlutterInjector'; +import FlutterLoader from './loader/FlutterLoader'; +import common from '@ohos.app.ability.common'; +import resourceManager from '@ohos.resourceManager'; +import FlutterNapi from './FlutterNapi'; +import NavigationChannel from './systemchannels/NavigationChannel'; +import Log from '../../util/Log'; +import TestChannel from './systemchannels/TestChannel' +import FlutterEngineConnectionRegistry from './FlutterEngineConnectionRegistry'; +import PluginRegistry from './plugins/PluginRegistry'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import TextInputChannel from './systemchannels/TextInputChannel'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import PlatformChannel from './systemchannels/PlatformChannel'; +import FlutterEngineGroup from './FlutterEngineGroup'; +import SystemChannel from './systemchannels/SystemChannel'; +import MouseCursorChannel from './systemchannels/MouseCursorChannel'; +import RestorationChannel from './systemchannels/RestorationChannel'; +import LocalizationChannel from './systemchannels/LocalizationChannel'; +import AccessibilityChannel from './systemchannels/AccessibilityChannel'; +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin' +import SettingsChannel from './systemchannels/SettingsChannel'; +import PlatformViewsController from '../../plugin/platform/PlatformViewsController'; + +const TAG = "FlutterEngine"; + +/** + * 操作FlutterEngin相关 + */ +export default class FlutterEngine implements EngineLifecycleListener{ + private engineLifecycleListeners = new Set(); + + dartExecutor: DartExecutor; + private flutterLoader: FlutterLoader; + private assetManager: resourceManager.ResourceManager; + //channel定义 + private lifecycleChannel: LifecycleChannel; + private navigationChannel: NavigationChannel; + private textInputChannel: TextInputChannel; + private testChannel: TestChannel; + private platformChannel: PlatformChannel; + private systemChannel: SystemChannel; + private mouseCursorChannel: MouseCursorChannel; + private restorationChannel: RestorationChannel; + + private accessibilityChannel: AccessibilityChannel; + private localeChannel: LocalizationChannel; + private flutterNapi: FlutterNapi; + private pluginRegistry: FlutterEngineConnectionRegistry; + private textInputPlugin: TextInputPlugin; + private localizationPlugin: LocalizationPlugin; + private settingsChannel: SettingsChannel; + private platformViewsController: PlatformViewsController; + + /** + * 需要初始化的工作: + * 1、初始化DartExecutor + * 2、初始化所有channel + * 3、初始化plugin + * 4、初始化flutterLoader + * 5、初始化flutterNapi + * 6、engineLifecycleListeners + */ + constructor(context: common.Context, flutterLoader: FlutterLoader, flutterNapi: FlutterNapi, platformViewsController: PlatformViewsController) { + const injector: FlutterInjector = FlutterInjector.getInstance(); + + if(flutterNapi == null){ + flutterNapi = FlutterInjector.getInstance().getFlutterNapi(); + } + this.flutterNapi = flutterNapi; + this.assetManager = context.resourceManager; + + this.dartExecutor = new DartExecutor(this.flutterNapi, this.assetManager); + this.dartExecutor.onAttachedToNAPI(); + + if(flutterLoader == null){ + flutterLoader = injector.getFlutterLoader(); + } + this.flutterLoader = flutterLoader; + + if(platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + this.platformViewsController = platformViewsController; + this.platformViewsController.attach(context, null, this.dartExecutor); + } + + async init(context: common.Context, dartVmArgs: Array, automaticallyRegisterPlugins: boolean, + waitForRestorationData: boolean, group: FlutterEngineGroup) { + if (!this.flutterNapi.isAttached()) { + await this.flutterLoader.startInitialization(context) + this.flutterLoader.ensureInitializationComplete(dartVmArgs); + } + //channel初始化 + this.lifecycleChannel = new LifecycleChannel(this.dartExecutor); + this.navigationChannel = new NavigationChannel(this.dartExecutor); + this.textInputChannel = new TextInputChannel(this.dartExecutor); + this.testChannel = new TestChannel(this.dartExecutor); + this.platformChannel = new PlatformChannel(this.dartExecutor); + this.systemChannel = new SystemChannel(this.dartExecutor); + this.mouseCursorChannel = new MouseCursorChannel(this.dartExecutor); + this.restorationChannel = new RestorationChannel(this.dartExecutor, waitForRestorationData); + this.settingsChannel = new SettingsChannel(this.dartExecutor); + + this.localeChannel = new LocalizationChannel(this.dartExecutor); + this.accessibilityChannel = new AccessibilityChannel(this.dartExecutor, this.flutterNapi); + this.flutterNapi.addEngineLifecycleListener(this); + this.localizationPlugin = new LocalizationPlugin(context, this.localeChannel); + + // It should typically be a fresh, unattached NAPI. But on a spawned engine, the NAPI instance + // is already attached to a native shell. In that case, the Java FlutterEngine is created around + // an existing shell. + if (!this.flutterNapi.isAttached()) { + this.attachToNapi(); + } + + this.pluginRegistry = new FlutterEngineConnectionRegistry(context.getApplicationContext(), this, this.flutterLoader, group); + this.localizationPlugin.sendLocaleToFlutter(); + } + + private attachToNapi(): void { + Log.d(TAG, "Attaching to NAPI."); + this.flutterNapi.attachToNative(); + + if (!this.isAttachedToNapi()) { + throw new Error("FlutterEngine failed to attach to its native Object reference."); + } + this.flutterNapi.setLocalizationPlugin(this.localizationPlugin); + } + + async spawn(context: common.Context, + dartEntrypoint: DartEntrypoint, + initialRoute: string, + dartEntrypointArgs: Array, + platformViewsController: PlatformViewsController, + automaticallyRegisterPlugins: boolean, waitForRestorationData: boolean) { + if (!this.isAttachedToNapi()) { + throw new Error( + "Spawn can only be called on a fully constructed FlutterEngine"); + } + + const newFlutterNapi = + this.flutterNapi.spawn( + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + initialRoute, + dartEntrypointArgs); + const flutterEngine = new FlutterEngine( + context, + null, + newFlutterNapi, + platformViewsController + ); + await flutterEngine.init(context, null, automaticallyRegisterPlugins, waitForRestorationData, null) + return flutterEngine + } + + private isAttachedToNapi(): boolean { + return this.flutterNapi.isAttached(); + } + + getLifecycleChannel(): LifecycleChannel { + return this.lifecycleChannel; + } + + getNavigationChannel(): NavigationChannel { + return this.navigationChannel; + } + + getTextInputChannel(): TextInputChannel { + return this.textInputChannel; + } + + getPlatformChannel(): PlatformChannel { + return this.platformChannel; + } + + getSystemChannel(): SystemChannel { + return this.systemChannel; + } + + getLocaleChannel(): LocalizationChannel { + return this.localeChannel; + } + + getMouseCursorChannel(): MouseCursorChannel { + return this.mouseCursorChannel; + } + + getFlutterNapi(): FlutterNapi { + return this.flutterNapi; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor + } + + getPlugins(): PluginRegistry { + return this.pluginRegistry; + } + + getAbilityControlSurface(): AbilityControlSurface { + return this.pluginRegistry; + } + + getSettingsChannel() { + return this.settingsChannel; + } + + onPreEngineRestart(): void { + + } + + onEngineWillDestroy(): void { + + } + + addEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(listener); + } + + removeEngineLifecycleListener(listener: EngineLifecycleListener): void { + this.engineLifecycleListeners.delete(listener); + } + + destroy(): void { + Log.d(TAG, "Destroying."); + this.engineLifecycleListeners.forEach(listener => listener.onEngineWillDestroy()) + this.flutterNapi.removeEngineLifecycleListener(this); + this.pluginRegistry.detachFromAbility(); + this.platformViewsController.onDetachedFromNapi(); + } + + getRestorationChannel(): RestorationChannel{ + return this.restorationChannel; + } + + getAccessibilityChannel(): AccessibilityChannel { + return this.accessibilityChannel; + } + + getLocalizationPlugin(): LocalizationPlugin { + return this.localizationPlugin; + } + + getSystemLanguages(): void { + return this.flutterNapi.getSystemLanguages(); + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } +} + +export interface EngineLifecycleListener { + onPreEngineRestart(): void; + + onEngineWillDestroy(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..78db31cae3a9d154a09f9f85541115dc4452573f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineCache.ets @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from "./FlutterEngine" + +export default class FlutterEngineCache { + private static instance : FlutterEngineCache; + private cachedEngines: Map = new Map(); + + static getInstance(): FlutterEngineCache { + if (FlutterEngineCache.instance == null) { + FlutterEngineCache.instance = new FlutterEngineCache(); + } + return FlutterEngineCache.instance; + } + /** + * 返回engineId对应的FlutterEngine是否存在 + */ + contains(engineId: String) : boolean { + return this.cachedEngines.has(engineId); + } + + /** + * 返回engineId对应的FlutterEngine + */ + get(engineId: String) : FlutterEngine { + return this.cachedEngines.get(engineId); + } + /** + * 将传入的FlutterEngine与engineId放在缓存中 + */ + put(engineId :String, engine: FlutterEngine): void { + if(engine != null) { + this.cachedEngines.set(engineId, engine); + } else { + this.cachedEngines.delete(engineId); + } + } + /** + * 移除engineId对应的FlutterEngine + */ + remove(engineId: String) : void { + this.put(engineId, null); + } + + /** + * 移除cachedEngines所有中所有的FlutterEngine + */ + clear():void { + this.cachedEngines.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..7709ea8a31e98f794314a7e2f3b84e890f1eee9f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineConnectionRegistry.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PluginRegistry from './plugins/PluginRegistry'; +import { FlutterAssets, FlutterPlugin, FlutterPluginBinding } from './plugins/FlutterPlugin'; +import FlutterEngine from './FlutterEngine'; +import AbilityAware from './plugins/ability/AbilityAware'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import { + AbilityPluginBinding, + WindowFocusChangedListener, + OnSaveStateListener, + NewWantListener +} from './plugins/ability/AbilityPluginBinding'; +import HashSet from '@ohos.util.HashSet'; +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import common from '@ohos.app.ability.common'; +import FlutterLoader from './loader/FlutterLoader'; +import Log from '../../util/Log'; +import ToolUtils from '../../util/ToolUtils'; +import AbilityControlSurface from './plugins/ability/AbilityControlSurface'; +import ExclusiveAppComponent from '../ohos/ExclusiveAppComponent'; +import FlutterEngineGroup from './FlutterEngineGroup'; + +const TAG = "FlutterEngineCxnRegstry"; + +export default class FlutterEngineConnectionRegistry implements PluginRegistry, AbilityControlSurface { + // PluginRegistry + private plugins = new Map(); + + // Standard FlutterPlugin + private flutterEngine: FlutterEngine; + private pluginBinding: FlutterPluginBinding; + + // AbilityAware + private abilityAwarePlugins = new Map(); + + private exclusiveAbility: ExclusiveAppComponent; + private abilityPluginBinding: FlutterEngineAbilityPluginBinding; + + constructor(appContext: common.Context, flutterEngine: FlutterEngine, flutterLoader: FlutterLoader, group: FlutterEngineGroup) { + this.flutterEngine = flutterEngine; + this.pluginBinding = new FlutterPluginBinding(appContext, this.flutterEngine.getDartExecutor(), new DefaultFlutterAssets(flutterLoader), group, this.flutterEngine.getPlatformViewsController()?.getRegistry()); + } + + add(plugin: FlutterPlugin): void { + try { + if (this.has(plugin.getUniqueClassName())) { + Log.w( + TAG, + "Attempted to register plugin (" + + plugin + + ") but it was " + + "already registered with this FlutterEngine (" + + this.flutterEngine + + ")."); + return; + } + + Log.w(TAG, "Adding plugin: " + plugin); + // Add the plugin to our generic set of plugins and notify the plugin + // that is has been attached to an engine. + this.plugins.set(plugin.getUniqueClassName(), plugin); + plugin.onAttachedToEngine(this.pluginBinding); + + // For AbilityAware plugins, add the plugin to our set of AbilityAware + // plugins, and if this engine is currently attached to an Ability, + // notify the AbilityAware plugin that it is now attached to an Ability. + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + const abilityAware: ESObject = plugin; + this.abilityAwarePlugins.set(plugin.getUniqueClassName(), abilityAware); + if (this.isAttachedToAbility()) { + abilityAware.onAttachedToAbility(this.abilityPluginBinding); + } + } + } finally { + + } + } + + addList(plugins: Set): void { + plugins.forEach(plugin => this.add(plugin)) + } + + has(pluginClassName: string): boolean { + return this.plugins.has(pluginClassName); + } + + get(pluginClassName: string): FlutterPlugin { + return this.plugins.get(pluginClassName); + } + + remove(pluginClassName: string): void { + const plugin = this.plugins.get(pluginClassName); + if (plugin == null) { + return; + } + if (ToolUtils.implementsInterface(plugin, "onAttachedToAbility")) { + if (this.isAttachedToAbility()) { + const abilityAware: ESObject = plugin; + abilityAware.onDetachedFromAbility(); + } + this.abilityAwarePlugins.delete(pluginClassName); + } + // Notify the plugin that is now detached from this engine. Then remove + // it from our set of generic plugins. + plugin.onDetachedFromEngine(this.pluginBinding); + this.plugins.delete(pluginClassName) + } + + removeList(pluginClassNames: Set): void { + pluginClassNames.forEach(plugin => this.remove(plugin)) + } + + removeAll(): void { + this.removeList(new Set(this.plugins.keys())); + this.plugins.clear(); + } + + private isAttachedToAbility(): boolean { + return this.exclusiveAbility != null; + } + + attachToAbility(exclusiveAbility: ExclusiveAppComponent): void { + if (this.exclusiveAbility != null) { + this.exclusiveAbility.detachFromFlutterEngine(); + } + // If we were already attached to an app component, detach from it. + this.detachFromAppComponent(); + this.exclusiveAbility = exclusiveAbility; + this.attachToAbilityInternal(exclusiveAbility.getAppComponent(),); + } + + detachFromAbility(): void { + if (this.isAttachedToAbility()) { + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onDetachedFromAbility()) + this.detachFromAbilityInternal(); + } else { + Log.e(TAG, "Attempted to detach plugins from an Ability when no Ability was attached."); + } + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.abilityPluginBinding.onNewWant(want, launchParams); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.abilityPluginBinding.onWindowFocusChanged(hasFocus); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + return this.abilityPluginBinding.onSaveState(reason, wantParam); + } + + private detachFromAppComponent(): void { + if (this.isAttachedToAbility()) { + this.detachFromAbility(); + } + } + + private attachToAbilityInternal(ability: UIAbility): void { + this.abilityPluginBinding = new FlutterEngineAbilityPluginBinding(ability); + // Notify all AbilityAware plugins that they are now attached to a new Ability. + this.abilityAwarePlugins.forEach(abilityAware => abilityAware.onAttachedToAbility(this.abilityPluginBinding)); + } + + private detachFromAbilityInternal(): void { + this.exclusiveAbility = null; + this.abilityPluginBinding = null; + } + + destroy(): void{ + this.detachFromAppComponent(); + // Remove all registered plugins. + this.removeAll(); + } +} + +class FlutterEngineAbilityPluginBinding implements AbilityPluginBinding { + private ability: UIAbility; + private onNewWantListeners = new HashSet(); + private onWindowFocusChangedListeners = new HashSet(); + private onSaveStateListeners = new HashSet(); + + constructor(ability: UIAbility) { + this.ability = ability; + + } + + getAbility(): UIAbility { + return this.ability; + } + + addOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.add(listener) + } + + removeOnNewWantListener(listener: NewWantListener): void { + this.onNewWantListeners.remove(listener) + } + + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.add(listener) + } + + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void { + this.onWindowFocusChangedListeners.remove(listener) + } + + addOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.add(listener) + } + + removeOnSaveStateListener(listener: OnSaveStateListener) { + this.onSaveStateListeners.remove(listener) + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.onNewWantListeners.forEach((listener, key) => { + listener.onNewWant(want, launchParams) + }); + } + + onWindowFocusChanged(hasFocus: boolean): void { + this.onWindowFocusChangedListeners.forEach((listener, key) => { + listener.onWindowFocusChanged(hasFocus) + }); + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + this.onSaveStateListeners.forEach((listener, key) => { + listener.onSaveState(reason, wantParam) + }); + return AbilityConstant.OnSaveResult.ALL_AGREE; + } +} + +class DefaultFlutterAssets implements FlutterAssets { + private flutterLoader: FlutterLoader; + + constructor(flutterLoader: FlutterLoader) { + this.flutterLoader = flutterLoader; + } + + getAssetFilePathByName(assetFileName: string, packageName?: string): string { + return this.flutterLoader.getLookupKeyForAsset(assetFileName, packageName); + } + + getAssetFilePathBySubpath(assetSubpath: string, packageName?: string) { + return this.flutterLoader.getLookupKeyForAsset(assetSubpath, packageName); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets new file mode 100644 index 0000000000000000000000000000000000000000..05e35aec1b7b6f50ab8df336bdd69fbbe21febc8 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroup.ets @@ -0,0 +1,184 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine, { EngineLifecycleListener } from "./FlutterEngine" +import common from '@ohos.app.ability.common' +import FlutterLoader from './loader/FlutterLoader' +import FlutterInjector from '../../FlutterInjector' +import { DartEntrypoint } from './dart/DartExecutor' +import PlatformViewsController from '../../plugin/platform/PlatformViewsController' +import ArrayList from '@ohos.util.ArrayList' + +export default class FlutterEngineGroup { + private activeEngines: ArrayList = new ArrayList(); + + constructor() { + + } + + async checkLoader(context: common.Context, args: Array) { + let loader: FlutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!loader.initialized) { + await loader.startInitialization(context.getApplicationContext()); + loader.ensureInitializationComplete(args); + } + } + + async createAndRunEngineByOptions(options: Options) { + let engine: FlutterEngine = null; + let context: common.Context = options.getContext(); + let dartEntrypoint: DartEntrypoint = options.getDartEntrypoint(); + let initialRoute: string = options.getInitialRoute(); + let dartEntrypointArgs: Array = options.getDartEntrypointArgs(); + let platformViewsController: PlatformViewsController = options.getPlatformViewsController(); + let automaticallyRegisterPlugins: boolean = options.getAutomaticallyRegisterPlugins(); + let waitForRestorationData: boolean = options.getWaitForRestorationData(); + + if (dartEntrypoint == null) { + dartEntrypoint = DartEntrypoint.createDefault(); + } + + if (platformViewsController == null) { + platformViewsController = new PlatformViewsController(); + } + + if (this.activeEngines.length == 0) { + engine = this.createEngine(context, platformViewsController); + await engine.init(context, null, // String[]. The Dart VM has already started, this arguments will have no effect. + automaticallyRegisterPlugins, // boolean. + waitForRestorationData, // boolean. + this) + if (initialRoute != null) { + engine.getNavigationChannel().setInitialRoute(initialRoute); + } + } else { + engine = await this.activeEngines[0] + .spawn( + context, + dartEntrypoint, + initialRoute, + dartEntrypointArgs, + platformViewsController, + automaticallyRegisterPlugins, + waitForRestorationData); + } + this.activeEngines.add(engine); + + const engineToCleanUpOnDestroy = engine; + let listener: EngineLifecycleListener = new EngineLifecycleListenerImpl( + platformViewsController, + this.activeEngines, + engineToCleanUpOnDestroy); + engine.addEngineLifecycleListener(listener); + return engine; + } + + createEngine(context: common.Context, platformViewsController: PlatformViewsController): FlutterEngine { + return new FlutterEngine(context, null, null, platformViewsController); + } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private platformViewsController: PlatformViewsController; + private activeEngines: ArrayList = new ArrayList(); + private engine: FlutterEngine; + + constructor( + platformViewsController: PlatformViewsController, + activeEngines: ArrayList, + engine: FlutterEngine) { + this.platformViewsController = platformViewsController; + this.activeEngines = activeEngines; + this.engine = engine; + } + onPreEngineRestart(): void { + this.platformViewsController.onPreEngineRestart(); + } + onEngineWillDestroy(): void { + this.activeEngines.remove(this.engine); + } +} + +export class Options { + private context: common.Context; + private dartEntrypoint: DartEntrypoint; + private initialRoute: string; + private dartEntrypointArgs: Array; + private platformViewsController: PlatformViewsController; + private automaticallyRegisterPlugins: boolean = true; + private waitForRestorationData: boolean = false; + + constructor(context: common.Context) { + this.context = context; + } + + getContext(): common.Context { + return this.context; + } + + getDartEntrypoint(): DartEntrypoint { + return this.dartEntrypoint; + } + + getInitialRoute(): string { + return this.initialRoute; + } + + getDartEntrypointArgs(): Array { + return this.dartEntrypointArgs; + } + + getAutomaticallyRegisterPlugins(): boolean { + return this.automaticallyRegisterPlugins; + } + + getWaitForRestorationData(): boolean { + return this.waitForRestorationData; + } + + getPlatformViewsController(): PlatformViewsController { + return this.platformViewsController; + } + + setDartEntrypoint(dartEntrypoint: DartEntrypoint): Options { + this.dartEntrypoint = dartEntrypoint; + return this; + } + + setInitialRoute(initialRoute: string): Options { + this.initialRoute = initialRoute; + return this; + } + + setDartEntrypointArgs(dartEntrypointArgs: Array): Options { + this.dartEntrypointArgs = dartEntrypointArgs; + return this; + } + + setAutomaticallyRegisterPlugins(automaticallyRegisterPlugins: boolean): Options { + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + return this; + } + + setWaitForRestorationData(waitForRestorationData: boolean): Options { + this.waitForRestorationData = waitForRestorationData; + return this; + } + + setPlatformViewsController(platformViewsController: PlatformViewsController): Options { + this.platformViewsController = platformViewsController; + return this; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets new file mode 100644 index 0000000000000000000000000000000000000000..34b251069ce950ee8a0fb3d2f08b723a2d1e6f78 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngineGroupCache.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngineGroup from './FlutterEngineGroup'; + +export default class FlutterEngineGroupCache { + static readonly instance = new FlutterEngineGroupCache(); + + private cachedEngineGroups = new Map(); + + contains(engineGroupId: string): boolean { + return this.cachedEngineGroups.has(engineGroupId); + } + + get(engineGroupId: string): FlutterEngineGroup { + return this.cachedEngineGroups.get(engineGroupId); + } + + put(engineGroupId: string, engineGroup?: FlutterEngineGroup) { + if (engineGroup != null) { + this.cachedEngineGroups.set(engineGroupId, engineGroup); + } else { + this.cachedEngineGroups.delete(engineGroupId); + } + } + + clear(): void { + this.cachedEngineGroups.clear(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets new file mode 100644 index 0000000000000000000000000000000000000000..902699e44c585b355df699b78cca69b58f021055 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterNapi.ets @@ -0,0 +1,359 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import flutter from 'libflutter.so'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log'; +import resourceManager from '@ohos.resourceManager'; +import { PlatformMessageHandler } from './dart/PlatformMessageHandler'; +import { FlutterCallbackInformation } from '../../view/FlutterCallbackInformation'; +import image from '@ohos.multimedia.image'; +import { EngineLifecycleListener } from './FlutterEngine'; +import { ByteBuffer } from '../../util/ByteBuffer'; +import { Action } from '../../view/AccessibilityBridge' +import LocalizationPlugin from '../../plugin/localization/LocalizationPlugin'; +import i18n from '@ohos.i18n'; + +const TAG = "FlutterNapi"; + +enum ContextType { + APP_LIFECYCLE = 0, + JS_PAGE_LIFECYCLE, +} + +/** + * 提供arkTs的flutterNAPI接口 + */ +export default class FlutterNapi { + hasInit: boolean = false; + //是否已实现 + hasImplemented: boolean = false; + + nativeShellHolderId: number = null; + platformMessageHandler: PlatformMessageHandler; + private engineLifecycleListeners = new Set(); + accessibilityDelegate: AccessibilityDelegate; + localizationPlugin: LocalizationPlugin; + + /** + * 更新刷新率 + * @param rate + */ + updateRefreshRate(refreshRateFPS : number) { + flutter.nativeUpdateRefreshRate(refreshRateFPS); + } + + init(context: common.Context, + args: Array, + bundlePath: string, + appStoragePath: string, + engineCachesPath: string, + initTimeMillis: number) { + if (this.hasInit) { + throw Error("the engine has init"); + } + this.hasInit = true; + Log.w(TAG, "init: bundlePath=" + bundlePath + " appStoragePath=" + appStoragePath + " engineCachesPath=" + engineCachesPath + " args=" + JSON.stringify(args)); + flutter.nativeInit(context, args, bundlePath, appStoragePath, engineCachesPath, initTimeMillis); + } + + attachToNative(): void { + this.nativeShellHolderId = flutter.nativeAttach(this); + Log.w(TAG, "nativeShellHolderId=" + this.nativeShellHolderId); + } + + runBundleAndSnapshotFromLibrary( + bundlePath: string, + entrypointFunctionName: string, + pathToEntrypointFunction: string, + assetManager: resourceManager.ResourceManager, + entrypointArgs: Array) { + Log.w(TAG, "init: bundlePath=" + bundlePath + " entrypointFunctionName=" + entrypointFunctionName + " pathToEntrypointFunction=" + pathToEntrypointFunction + " entrypointArgs=" + JSON.stringify(entrypointArgs)) + flutter.nativeRunBundleAndSnapshotFromLibrary(this.nativeShellHolderId, bundlePath, entrypointFunctionName, pathToEntrypointFunction, assetManager, entrypointArgs); + }; + + /** + * 当前so方法是否都实现 + * @returns + */ + checkImplemented(methodName: string = ""): boolean { + if (!this.hasImplemented) { + Log.e(TAG, "this method has not implemented -> " + methodName) + } + return this.hasImplemented; + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.ensureRunningOnMainThread(); + this.platformMessageHandler = platformMessageHandler; + } + + private ensureAttachedToNative(): void { + if (this.nativeShellHolderId == null) { + throw new Error( + "Cannot execute operation because FlutterNapi is not attached to native."); + } + } + + private nativeNotifyLowMemoryWarning(nativeShellHolderId: number): void { + + } + + static nativeLookupCallbackInformation(handle: number): FlutterCallbackInformation { + return null; + } + + notifyLowMemoryWarning(): void { + this.ensureRunningOnMainThread(); + this.ensureAttachedToNative(); + this.nativeNotifyLowMemoryWarning(this.nativeShellHolderId); + } + + isAttached(): boolean { + return this.nativeShellHolderId != null; + } + + private ensureRunningOnMainThread(): void { + + } + + dispatchEmptyPlatformMessage(channel: String, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + flutter.nativeDispatchEmptyPlatformMessage(this.nativeShellHolderId, channel, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + /** Sends a reply {@code message} from Android to Flutter over the given {@code channel}. */ + dispatchPlatformMessage(channel: String, message: ArrayBuffer, position: number, responseId: number): void { + this.ensureRunningOnMainThread(); + if (this.isAttached()) { + + const uintArrayBuff = new Uint8Array(message) + let text = '' + for (let i = 0; i < uintArrayBuff.byteLength; i++) { + text += uintArrayBuff[i] + ',' + } + Log.w(TAG, "message=" + message.byteLength + ",text=" + text); + flutter.nativeDispatchPlatformMessage(this.nativeShellHolderId, channel, message, position, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message to Flutter, but FlutterNapi was detached from native C++. Could not send. Channel: " + + channel + + ". Response ID: " + + responseId); + } + } + + invokePlatformMessageEmptyResponseCallback(responseId: number): void { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageEmptyResponseCallback(this.nativeShellHolderId, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + invokePlatformMessageResponseCallback(responseId: number, message: ArrayBuffer, position: number) { + if (this.isAttached()) { + flutter.nativeInvokePlatformMessageResponseCallback( + this.nativeShellHolderId, responseId, message, position); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setViewportMetrics(devicePixelRatio: number, physicalWidth: number + , physicalHeight: number, physicalPaddingTop: number, physicalPaddingRight: number + , physicalPaddingBottom: number, physicalPaddingLeft: number, physicalViewInsetTop: number + , physicalViewInsetRight: number, physicalViewInsetBottom: number, physicalViewInsetLeft: number + , systemGestureInsetTop: number, systemGestureInsetRight: number, systemGestureInsetBottom: number + , systemGestureInsetLeft: number, physicalTouchSlop: number, displayFeaturesBounds: Array + , displayFeaturesType: Array, displayFeaturesState: Array): void { + if (this.isAttached()) { + flutter.nativeSetViewportMetrics(this.nativeShellHolderId, devicePixelRatio, + physicalWidth, + physicalHeight, + physicalPaddingTop, + physicalPaddingRight, + physicalPaddingBottom, + physicalPaddingLeft, + physicalViewInsetTop, + physicalViewInsetRight, + physicalViewInsetBottom, + physicalViewInsetLeft, + systemGestureInsetTop, + systemGestureInsetRight, + systemGestureInsetBottom, + systemGestureInsetLeft, + physicalTouchSlop, + displayFeaturesBounds, + displayFeaturesType, + displayFeaturesState); + } + } + + spawn(entrypointFunctionName: string, pathToEntrypointFunction: string, initialRoute: string, entrypointArgs: Array): FlutterNapi { + return new FlutterNapi(); + } + + addEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener): void { + this.engineLifecycleListeners.add(engineLifecycleListener); + } + + removeEngineLifecycleListener(engineLifecycleListener: EngineLifecycleListener) { + this.engineLifecycleListeners.delete(engineLifecycleListener); + } + + //Called by native to respond to a platform message that we sent. + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.w(TAG, "called handlePlatformMessageResponse Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handlePlatformMessageResponse(replyId, reply); + } + } + + // Called by native on any thread. + handlePlatformMessage(channel: string, message: ArrayBuffer, replyId: number, messageData: number): void { + Log.w(TAG, "called handlePlatformMessage Channel: " + channel + ". Response ID: " + replyId); + if (this.platformMessageHandler != null) { + this.platformMessageHandler.handleMessageFromDart(channel, message, replyId, messageData); + } + } + + // Called by native to notify first Flutter frame rendered. + onFirstFrame(): void { + Log.d(TAG, "called onFirstFrame") + } + + // Called by native. + onPreEngineRestart(): void { + Log.d(TAG, "called onPreEngineRestart") + this.engineLifecycleListeners.forEach( listener => listener.onPreEngineRestart()); + } + + // /** Invoked by native to obtain the results of OHOS's locale resolution algorithm. */ + computePlatformResolvedLocale(strings: Array): Array { + Log.d(TAG, "called computePlatformResolvedLocale " + JSON.stringify(strings)) + return [] + } + + decodeImage(buffer: ArrayBuffer, imageGeneratorAddress: number): void { + Log.d(TAG, "called decodeImage=" + buffer.byteLength) + const imageSourceApi = image.createImageSource(buffer); + let tempPixelMap: image.PixelMap = null; + imageSourceApi.createPixelMap({ + desiredPixelFormat: image.PixelMapFormat.RGBA_8888 + }).then(pixelMap => { + Log.d(TAG, "called createPixelMap end " + pixelMap.getPixelBytesNumber()) + tempPixelMap = pixelMap + return pixelMap.getImageInfo() + }).then(imageInfo => { + Log.d(TAG, `nativeImageHeaderCallback width=${imageInfo.size.width} height=${imageInfo.size.height} imageGeneratorAddress=${imageGeneratorAddress}`) + flutter.nativeImageDecodeCallback(imageInfo.size.width, imageInfo.size.height, imageGeneratorAddress, tempPixelMap) + }).catch((error: ESObject) => { + Log.d(TAG, "decodeImage error=" + JSON.stringify(error)) + flutter.nativeImageDecodeCallback(0, 0, imageGeneratorAddress, null); + }) + } + + setSemanticsEnabled(enabled: boolean, responseId: number): void { + if (this.isAttached()) { + this.nativeSetSemanticsEnabled(enabled); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + // Send an empty response to a platform message received from Dart. + nativeSetSemanticsEnabled(enabled: boolean):void {} + + setAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void { + if (this.isAttached()) { + this.nativeSetAccessibilityFeatures(accessibilityFeatureFlags, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeSetAccessibilityFeatures(accessibilityFeatureFlags: number, responseId: number): void {} + + dispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void { + if (this.isAttached()) { + this.nativeDispatchSemanticsAction(virtualViewId, action, responseId); + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + nativeDispatchSemanticsAction(virtualViewId: number, action: Action, responseId: number): void {} + + setAccessibilityDelegate(delegate: AccessibilityDelegate, responseId: number): void { + if (this.isAttached()) { + this.accessibilityDelegate = delegate; + } else { + Log.w( + TAG, + "Tried to send a platform message response, but FlutterNapi was detached from native C++. Could not send. Response ID: " + + responseId); + } + } + + setLocalizationPlugin(localizationPlugin: LocalizationPlugin): void { + this.localizationPlugin = localizationPlugin; + } + + /** + * 获取系统语言列表 + * @param rate + */ + getSystemLanguages() { + Log.d(TAG, "called getSystemLanguages ") + let index: number; + let systemLanguages = i18n.System.getPreferredLanguageList(); + for (index = 0; index < systemLanguages.length; index++) { + Log.d(TAG, "systemlanguages "+ index + ":" + systemLanguages[index]); + } + flutter.nativeGetSystemLanguages(this.nativeShellHolderId, systemLanguages); + } +} + +export interface AccessibilityDelegate { + updateCustomAccessibilityActions(buffer: ByteBuffer, strings: string[]): void; + + updateSemantics(buffer: ByteBuffer, strings: string[], stringAttributeArgs: ByteBuffer[]): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..2d63d83de313f52eba3f8fa6d2ed584f7bee44bd --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterOverlaySurface.ets @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterOverlaySurface { + + private id: number; + + constructor(id: number) { + this.id = id + } + + getId(): number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets new file mode 100644 index 0000000000000000000000000000000000000000..7a3cd75a49b7c53742072aa30541204060fc82e6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterShellArgs.ets @@ -0,0 +1,86 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Want from '@ohos.app.ability.Want'; + +/** + * 封装flutter shell的参数 + */ +export default class FlutterShellArgs { + static ARG_KEY_TRACE_STARTUP = "trace-startup"; + static ARG_TRACE_STARTUP = "--trace-startup"; + static ARG_KEY_START_PAUSED = "start-paused"; + static ARG_START_PAUSED = "--start-paused"; + static ARG_KEY_DISABLE_SERVICE_AUTH_CODES = "disable-service-auth-codes"; + static ARG_DISABLE_SERVICE_AUTH_CODES = "--disable-service-auth-codes"; + static ARG_KEY_ENDLESS_TRACE_BUFFER = "endless-trace-buffer"; + static ARG_ENDLESS_TRACE_BUFFER = "--endless-trace-buffer"; + static ARG_KEY_USE_TEST_FONTS = "use-test-fonts"; + static ARG_USE_TEST_FONTS = "--use-test-fonts"; + static ARG_KEY_ENABLE_DART_PROFILING = "enable-dart-profiling"; + static ARG_ENABLE_DART_PROFILING = "--enable-dart-profiling"; + static ARG_KEY_ENABLE_SOFTWARE_RENDERING = "enable-software-rendering"; + static ARG_ENABLE_SOFTWARE_RENDERING = "--enable-software-rendering"; + static ARG_KEY_SKIA_DETERMINISTIC_RENDERING = "skia-deterministic-rendering"; + static ARG_SKIA_DETERMINISTIC_RENDERING = "--skia-deterministic-rendering"; + static ARG_KEY_TRACE_SKIA = "trace-skia"; + static ARG_TRACE_SKIA = "--trace-skia"; + static ARG_KEY_TRACE_SKIA_ALLOWLIST = "trace-skia-allowlist"; + static ARG_TRACE_SKIA_ALLOWLIST = "--trace-skia-allowlist="; + static ARG_KEY_TRACE_SYSTRACE = "trace-systrace"; + static ARG_TRACE_SYSTRACE = "--trace-systrace"; + static ARG_KEY_ENABLE_IMPELLER = "enable-impeller"; + static ARG_ENABLE_IMPELLER = "--enable-impeller"; + static ARG_KEY_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "dump-skp-on-shader-compilation"; + static ARG_DUMP_SHADER_SKP_ON_SHADER_COMPILATION = + "--dump-skp-on-shader-compilation"; + static ARG_KEY_CACHE_SKSL = "cache-sksl"; + static ARG_CACHE_SKSL = "--cache-sksl"; + static ARG_KEY_PURGE_PERSISTENT_CACHE = "purge-persistent-cache"; + static ARG_PURGE_PERSISTENT_CACHE = "--purge-persistent-cache"; + static ARG_KEY_VERBOSE_LOGGING = "verbose-logging"; + static ARG_VERBOSE_LOGGING = "--verbose-logging"; + static ARG_KEY_OBSERVATORY_PORT = "observatory-port"; + static ARG_OBSERVATORY_PORT = "--observatory-port="; + static ARG_KEY_DART_FLAGS = "dart-flags"; + static ARG_DART_FLAGS = "--dart-flags"; + static ARG_KEY_MSAA_SAMPLES = "msaa-samples"; + static ARG_MSAA_SAMPLES = "--msaa-samples"; + + /** + * 从意图中解析参数,创建shellArgs + * @returns + */ + static fromWant(want: Want): FlutterShellArgs { + //tdo 解析want + return new FlutterShellArgs(); + } + + //参数 + args: Set = new Set(); + + add(arg: string) { + this.args.add(arg); + } + + remove(arg: string) { + this.args.delete(arg); + } + + toArray(): Array { + return Array.from(this.args); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets new file mode 100644 index 0000000000000000000000000000000000000000..8d97b4835c0c87ed0c9d9260336b3a338392497f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartExecutor.ets @@ -0,0 +1,379 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import resourceManager from '@ohos.resourceManager'; +import FlutterInjector from '../../../FlutterInjector'; +import { BinaryMessageHandler, BinaryReply, TaskQueue, TaskQueueOptions } from '../../../plugin/common/BinaryMessenger'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import StringCodec from '../../../plugin/common/StringCodec'; +import Log from '../../../util/Log'; +import { TraceSection } from '../../../util/TraceSection'; +import { FlutterCallbackInformation } from '../../../view/FlutterCallbackInformation'; +import FlutterNapi from '../FlutterNapi'; +import { DartMessenger } from './DartMessenger'; + + +const TAG = "DartExecutor"; + +/** + * dart代码执行器 + */ +export default class DartExecutor implements BinaryMessenger { + flutterNapi: FlutterNapi; + assetManager: resourceManager.ResourceManager; + private dartMessenger: DartMessenger; + private binaryMessenger: BinaryMessenger; + private isApplicationRunning: boolean; + private isolateServiceId: String = null; + private isolateServiceIdListener: IsolateServiceIdListener = null; + + private isolateChannelMessageHandler: BinaryMessageHandler = + new IsolateChannelMessageHandler(this.isolateServiceId, this.isolateServiceIdListener); + + constructor(flutterNapi: FlutterNapi, assetManager: resourceManager.ResourceManager) { + this.flutterNapi = flutterNapi; + this.assetManager = assetManager; + this.dartMessenger = new DartMessenger(flutterNapi); + this.dartMessenger.setMessageHandler("flutter/isolate", this.isolateChannelMessageHandler); + this.binaryMessenger = new DefaultBinaryMessenger(this.dartMessenger); + // The JNI might already be attached if coming from a spawned engine. If so, correctly report + // that this DartExecutor is already running. + if (flutterNapi.isAttached()) { + this.isApplicationRunning = true; + } + } + + + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * DartExecutor} attaches to JNI. + * + *

When attached to JNI, this {@link DartExecutor} begins handling 2-way communication to/from + * the Dart execution context. This communication is facilitate via 2 APIs: + * + *

    + *
  • {@link BinaryMessenger}, which sends messages to Dart + *
  • {@link PlatformMessageHandler}, which receives messages from Dart + *
+ */ + onAttachedToNAPI(): void { + Log.d(TAG, "Attached to NAPI. Registering the platform message handler for this Dart execution context."); + this.flutterNapi.setPlatformMessageHandler(this.dartMessenger); + } + + /** + * Invoked when the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@link + * DartExecutor} detaches from JNI. + * + *

When detached from JNI, this {@link DartExecutor} stops handling 2-way communication to/from + * the Dart execution context. + */ + onDetachedFromNAPI(): void { + Log.d(TAG, "Detached from NAPI. De-registering the platform message handler for this Dart execution context."); + this.flutterNapi.setPlatformMessageHandler(null); + } + + /** + * Is this {@link DartExecutor} currently executing Dart code? + * + * @return true if Dart code is being executed, false otherwise + */ + isExecutingDart(): boolean { + return this.isApplicationRunning; + } + + /** + * Starts executing Dart code based on the given {@code dartEntrypoint} and the {@code + * dartEntrypointArgs}. + * + *

See {@link DartEntrypoint} for configuration options. + * + * @param dartEntrypoint specifies which Dart function to run, and where to find it + * @param dartEntrypointArgs Arguments passed as a list of string to Dart's entrypoint function. + */ + executeDartEntrypoint(dartEntrypoint: DartEntrypoint, dartEntrypointArgs?: string[]): void { + if (this.isApplicationRunning) { + Log.w(TAG, "Attempted to run a DartExecutor that is already running."); + return; + } + + TraceSection.begin("DartExecutor#executeDartEntrypoint"); + try { + Log.d(TAG, "Executing Dart entrypoint: " + dartEntrypoint); + this.flutterNapi.runBundleAndSnapshotFromLibrary( + dartEntrypoint.pathToBundle, + dartEntrypoint.dartEntrypointFunctionName, + dartEntrypoint.dartEntrypointLibrary, + this.assetManager, + dartEntrypointArgs); + + this.isApplicationRunning = true; + } finally { + TraceSection.end("DartExecutor#executeDartEntrypoint"); + } + } + + /** + * Starts executing Dart code based on the given {@code dartCallback}. + * + *

See {@link DartCallback} for configuration options. + * + * @param dartCallback specifies which Dart callback to run, and where to find it + */ + executeDartCallback(dartCallback: DartCallback): void { + if (this.isApplicationRunning) { + Log.w(TAG, "Attempted to run a DartExecutor that is already running."); + return; + } + + TraceSection.begin("DartExecutor#executeDartCallback"); + try { + Log.d(TAG, "Executing Dart callback: " + dartCallback); + this.flutterNapi.runBundleAndSnapshotFromLibrary( + dartCallback.pathToBundle, + dartCallback.callbackHandle.callbackName, + dartCallback.callbackHandle.callbackLibraryPath, + dartCallback.resourceManager, + null); + + this.isApplicationRunning = true; + } finally { + TraceSection.end("DartExecutor#executeDartCallback"); + } + } + + /** + * Returns a {@link BinaryMessenger} that can be used to send messages to, and receive messages + * from, Dart code that this {@code DartExecutor} is executing. + */ + + getBinaryMessenger(): BinaryMessenger { + return this.binaryMessenger; + } + + makeBackgroundTaskQueue(options: TaskQueueOptions): TaskQueue { + return this.getBinaryMessenger().makeBackgroundTaskQueue(options); + } + + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + this.getBinaryMessenger().send(channel, message, callback); + } + + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void { + this.getBinaryMessenger().setMessageHandler(channel, handler, taskQueue); + } + + enableBufferingIncomingMessages(): void { + this.getBinaryMessenger().enableBufferingIncomingMessages(); + } + + + /** + * Returns the number of pending channel callback replies. + * + *

When sending messages to the Flutter application using {@link BinaryMessenger#send(String, + * ByteBuffer, io.flutter.plugin.common.BinaryMessenger.BinaryReply)}, developers can optionally + * specify a reply callback if they expect a reply from the Flutter application. + * + *

This method tracks all the pending callbacks that are waiting for response, and is supposed + * to be called from the main thread (as other methods). Calling from a different thread could + * possibly capture an indeterministic internal state, so don't do it. + * + *

Currently, it's mainly useful for a testing framework like Espresso to determine whether all + * the async channel callbacks are handled and the app is idle. + */ + getPendingChannelResponseCount(): number { + return this.dartMessenger.getPendingChannelResponseCount(); + } + + /** + * Returns an identifier for this executor's primary isolate. This identifier can be used in + * queries to the Dart service protocol. + */ + + getIsolateServiceId(): String { + return this.isolateServiceId; + } + + + + /** + * Set a listener that will be notified when an isolate identifier is available for this + * executor's primary isolate. + */ + setIsolateServiceIdListener(listener: IsolateServiceIdListener): void { + this.isolateServiceIdListener = listener; + if (this.isolateServiceIdListener != null && this.isolateServiceId != null) { + this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); + } + } + + /** + * Notify the Dart VM of a low memory event, or that the application is in a state such that now + * is an appropriate time to free resources, such as going to the background. + * + *

This does not notify a Flutter application about memory pressure. For that, use the {@link + * io.flutter.embedding.engine.systemchannels.SystemChannel#sendMemoryPressureWarning}. + * + *

Calling this method may cause jank or latency in the application. Avoid calling it during + * critical periods like application startup or periods of animation. + */ + notifyLowMemoryWarning(): void { + if (this.flutterNapi.isAttached()) { + this.flutterNapi.notifyLowMemoryWarning(); + } + } + + disableBufferingIncomingMessages(): void { + this.getBinaryMessenger().enableBufferingIncomingMessages(); + } +} + + +/** + * Configuration options that specify which Dart entrypoint function is executed and where to find + * that entrypoint and other assets required for Dart execution. + */ +export class DartEntrypoint { + /** The path within the AssetManager where the app will look for assets. */ + pathToBundle: string; + + /** The library or file location that contains the Dart entrypoint function. */ + dartEntrypointLibrary: string; + + /** The name of a Dart function to execute. */ + dartEntrypointFunctionName: string; + + constructor(pathToBundle: string, + dartEntrypointLibrary: string, + dartEntrypointFunctionName: string) { + this.pathToBundle = pathToBundle; + this.dartEntrypointLibrary = dartEntrypointLibrary; + this.dartEntrypointFunctionName = dartEntrypointFunctionName; + } + + static createDefault() { + const flutterLoader = FlutterInjector.getInstance().getFlutterLoader(); + if (!flutterLoader.initialized) { + throw new Error( + "DartEntrypoints can only be created once a FlutterEngine is created."); + } + return new DartEntrypoint(flutterLoader.findAppBundlePath(), null, "main"); + } +} + + +/** Callback interface invoked when the isolate identifier becomes available. */ +interface IsolateServiceIdListener { + onIsolateServiceIdAvailable(isolateServiceId: String): void; +} + + +/** + * Configuration options that specify which Dart callback function is executed and where to find + * that callback and other assets required for Dart execution. + */ +export class DartCallback { + /** Standard Android AssetManager, provided from some {@code Context} or {@code Resources}. */ + public resourceManager: resourceManager.ResourceManager; + + /** The path within the AssetManager where the app will look for assets. */ + public pathToBundle: string; + + /** A Dart callback that was previously registered with the Dart VM. */ + public callbackHandle: FlutterCallbackInformation; + + constructor(resourceManager: resourceManager.ResourceManager, + pathToBundle: string, + callbackHandle: FlutterCallbackInformation) { + this.resourceManager = resourceManager; + this.pathToBundle = pathToBundle; + this.callbackHandle = callbackHandle; + } + + toString(): String { + return "DartCallback( bundle path: " + + this.pathToBundle + + ", library path: " + + this.callbackHandle.callbackLibraryPath + + ", function: " + + this.callbackHandle.callbackName + + " )"; + } +} + +export class DefaultBinaryMessenger implements BinaryMessenger { + private messenger: DartMessenger; + + constructor(messenger: DartMessenger) { + this.messenger = messenger; + } + + makeBackgroundTaskQueue(options: TaskQueueOptions): TaskQueue { + return this.messenger.makeBackgroundTaskQueue(options); + } + + /** + * Sends the given {@code messages} from Android to Dart over the given {@code channel} and then + * has the provided {@code callback} invoked when the Dart side responds. + * + * @param channel the name of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a callback invoked when the Dart application responds to the message + */ + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + this.messenger.send(channel, message, callback); + } + + /** + * Sets the given {@link io.flutter.plugin.common.BinaryMessenger.BinaryMessageHandler} as the + * singular handler for all incoming messages received from the Dart side of this Dart execution + * context. + * + * @param channel the name of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + */ + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void { + this.messenger.setMessageHandler(channel, handler); + } + + enableBufferingIncomingMessages(): void { + this.messenger.enableBufferingIncomingMessages(); + } + + disableBufferingIncomingMessages(): void { + this.messenger.disableBufferingIncomingMessages(); + } +} + +class IsolateChannelMessageHandler implements BinaryMessageHandler { + private isolateServiceId: String; + private isolateServiceIdListener: IsolateServiceIdListener; + + constructor(isolateServiceId: String, isolateServiceIdListener: IsolateServiceIdListener) { + this.isolateServiceId = isolateServiceId; + this.isolateServiceIdListener = isolateServiceIdListener; + } + + onMessage(message: ArrayBuffer, callback: BinaryReply): void { + this.isolateServiceId = StringCodec.INSTANCE.decodeMessage(message); + if (this.isolateServiceIdListener != null) { + this.isolateServiceIdListener.onIsolateServiceIdAvailable(this.isolateServiceId); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b8695530d69f9e49063913d559702863490676a --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/DartMessenger.ets @@ -0,0 +1,236 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log' +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue, TaskQueueOptions } from '../../../plugin/common/BinaryMessenger'; +import FlutterNapi from '../FlutterNapi'; +import { PlatformMessageHandler } from './PlatformMessageHandler'; +import { TraceSection } from '../../../util/TraceSection'; + +/** + * Message conduit for 2-way communication between Android and Dart. + * + *

See {@link BinaryMessenger}, which sends messages from Android to Dart + * + *

See {@link PlatformMessageHandler}, which handles messages to Android from Dart + */ + +const TAG = "DartMessenger"; + +export class DartMessenger implements BinaryMessenger, PlatformMessageHandler { + + flutterNapi: FlutterNapi; + + /** + * Maps a channel name to an object that contains the task queue and the handler associated with + * the channel. + * + *

Reads and writes to this map must lock {@code handlersLock}. + */ + messageHandlers: Map = new Map(); + + /** + * Maps a channel name to an object that holds information about the incoming Dart message. + * + *

Reads and writes to this map must lock {@code handlersLock}. + */ + bufferedMessages: Map = new Map(); + + handlersLock: Object = new Object(); + enableBufferingIncomingMessagesFlag: boolean = false; + + pendingReplies: Map = new Map(); + nextReplyId: number = 1; + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi; + } + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue { + throw new Error('Method not implemented.'); + } + + + setMessageHandler(channel: String, handler: BinaryMessageHandler): void { + if (handler == null) { + Log.d(TAG, "Removing handler for channel '" + channel + "'"); + this.messageHandlers.delete(channel); + return; + } + Log.d(TAG, "Setting handler for channel '" + channel + "'"); + + this.messageHandlers.set(channel, new HandlerInfo(handler)); + this.bufferedMessages.delete(channel); + } + + + enableBufferingIncomingMessages(): void { + this.enableBufferingIncomingMessagesFlag = true; + } + + disableBufferingIncomingMessages(): void { + this.enableBufferingIncomingMessagesFlag = false; + this.bufferedMessages = new Map(); + } + + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void { + Log.d(TAG, "Sending message over channel '" + channel + "'"); + TraceSection.begin("DartMessenger#send on " + channel); + try { + Log.d(TAG, "Sending message with callback over channel '" + channel + "'"); + let replyId: number = this.nextReplyId++; + if (callback != null) { + this.pendingReplies.set(replyId, callback); + } + if (message == null) { + this.flutterNapi.dispatchEmptyPlatformMessage(channel, replyId); + } else { + this.flutterNapi.dispatchPlatformMessage(channel, message, message.byteLength, replyId); + } + } finally { + TraceSection.end("DartMessenger#send on " + channel); + } + } + + invokeHandler(handlerInfo: HandlerInfo, message: ArrayBuffer, replyId: number): void { + // Called from any thread. + if (handlerInfo != null) { + try { + Log.d(TAG, "Deferring to registered handler to process message."); + handlerInfo.handler.onMessage(message, new Reply(this.flutterNapi, replyId)); + } catch (ex) { + Log.e(TAG, "Uncaught exception in binary message listener", ex); + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); + } + } else { + Log.d(TAG, "No registered handler for message. Responding to Dart with empty reply message."); + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(replyId); + } + } + + handleMessageFromDart(channel: String, message: ArrayBuffer, replyId: number, messageData: number): void { + // Called from any thread. + Log.d(TAG, "Received message from Dart over channel '" + channel + "'"); + + let handlerInfo: HandlerInfo; + let messageDeferred: boolean; + handlerInfo = this.messageHandlers.get(channel); + messageDeferred = (this.enableBufferingIncomingMessagesFlag && handlerInfo == null); + if (messageDeferred) { + if (!this.bufferedMessages.has(channel)) { + // this.bufferedMessages.set(channel, new BufferedMessageInfo[0]); + this.bufferedMessages.set(channel, null); + } + let buffer: BufferedMessageInfo[] = this.bufferedMessages.get(channel); + buffer.push(new BufferedMessageInfo(message, replyId, messageData)); + } + if (!messageDeferred) { + this.invokeHandler(handlerInfo, message, replyId); + } + } + + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void { + Log.d(TAG, "Received message reply from Dart."); + let callback: BinaryReply = this.pendingReplies.get(replyId); + this.pendingReplies.delete(replyId); + if (callback != null) { + try { + Log.d(TAG, "Invoking registered callback for reply from Dart."); + callback.reply(reply); + } catch (e) { + Log.e(TAG, "Uncaught exception in binary message reply handler", e); + } + } + } + + /** + * Returns the number of pending channel callback replies. + * + *

When sending messages to the Flutter application using {@link BinaryMessenger#send(String, + * ByteBuffer, io.flutter.plugin.common.BinaryMessenger.BinaryReply)}, developers can optionally + * specify a reply callback if they expect a reply from the Flutter application. + * + *

This method tracks all the pending callbacks that are waiting for response, and is supposed + * to be called from the main thread (as other methods). Calling from a different thread could + * possibly capture an indeterministic internal state, so don't do it. + */ + getPendingChannelResponseCount(): number { + return this.pendingReplies.size; + } +} + + + + + + +/** + * Holds information about a platform handler, such as the task queue that processes messages from + * Dart. + */ +class HandlerInfo { + handler: BinaryMessageHandler; + + constructor(handler: BinaryMessageHandler) { + this.handler = handler; + } +} + +/** + * Holds information that allows to dispatch a Dart message to a platform handler when it becomes + * available. + */ +class BufferedMessageInfo { + message: ArrayBuffer; + replyId: number; + messageData: number; + + constructor(message: ArrayBuffer, + replyId: number, + messageData: number) { + this.message = message; + this.replyId = replyId; + this.messageData = messageData; + } +} + + + + + +class Reply implements BinaryReply { + flutterNapi: FlutterNapi; + replyId: number; + done: boolean = false; + + constructor(flutterNapi: FlutterNapi, replyId: number) { + this.flutterNapi = flutterNapi; + this.replyId = replyId; + } + + reply(reply: ArrayBuffer) { + if (this.done) { + throw new Error("Reply already submitted"); + } + if (reply == null) { + this.flutterNapi.invokePlatformMessageEmptyResponseCallback(this.replyId); + } else { + this.flutterNapi.invokePlatformMessageResponseCallback(this.replyId, reply, reply.byteLength); + } + } +} + +interface DartMessengerTaskQueue { + dispatch(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets new file mode 100644 index 0000000000000000000000000000000000000000..b6e3411862cb936f4e9af2c6e0ab6a49be3c9dce --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/dart/PlatformMessageHandler.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export interface PlatformMessageHandler { + + handleMessageFromDart(channel: String,message: ArrayBuffer,replyId: number, messageData: number): void; + + handlePlatformMessageResponse(replyId: number, reply: ArrayBuffer): void; + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets new file mode 100644 index 0000000000000000000000000000000000000000..b8af4f6fb756f4e344e5040d828244ada46d0783 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/ApplicationInfoLoader.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterApplicationInfo from './FlutterApplicationInfo'; +import common from '@ohos.app.ability.common'; + +export default class ApplicationInfoLoader { + static load(context: common.Context) { + let applicatioinInfo = new FlutterApplicationInfo(null, null, null, null, null, context.bundleCodeDir + '/libs/arm64', true); + return applicatioinInfo + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets new file mode 100644 index 0000000000000000000000000000000000000000..0db68ee9da2876e12e9c50734c68c2781469b0c4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterApplicationInfo.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +const DEFAULT_AOT_SHARED_LIBRARY_NAME = "libapp.so"; +const DEFAULT_VM_SNAPSHOT_DATA = "vm_snapshot_data"; +const DEFAULT_ISOLATE_SNAPSHOT_DATA = "isolate_snapshot_data"; +const DEFAULT_FLUTTER_ASSETS_DIR = "flutter_assets"; + + +/** + * application 信息,后期看如何设置 + */ +export default class FlutterApplicationInfo { + aotSharedLibraryName: string; + vmSnapshotData: string; + isolateSnapshotData: string; + flutterAssetsDir: string; + domainNetworkPolicy: string; + nativeLibraryDir: string; + automaticallyRegisterPlugins: boolean; + //是否是开发模式,先放在这里,后续应该从context获取 + isDebugMode: boolean; + //是否是profile模式 + isProfile: boolean; + + constructor(aotSharedLibraryName: string, vmSnapshotData: string, isolateSnapshotData: string, flutterAssetsDir: string, domainNetworkPolicy: string, + nativeLibraryDir: string, automaticallyRegisterPlugins: boolean) { + this.aotSharedLibraryName = aotSharedLibraryName == null ? DEFAULT_AOT_SHARED_LIBRARY_NAME : aotSharedLibraryName; + this.vmSnapshotData = vmSnapshotData == null ? DEFAULT_VM_SNAPSHOT_DATA : vmSnapshotData; + this.isolateSnapshotData = isolateSnapshotData == null ? DEFAULT_ISOLATE_SNAPSHOT_DATA : isolateSnapshotData; + this.flutterAssetsDir = flutterAssetsDir == null ? DEFAULT_FLUTTER_ASSETS_DIR : flutterAssetsDir; + this.domainNetworkPolicy = domainNetworkPolicy == null ? "" : domainNetworkPolicy; + this.nativeLibraryDir = nativeLibraryDir; + this.automaticallyRegisterPlugins = automaticallyRegisterPlugins; + this.isDebugMode = true; + this.isProfile = false; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets new file mode 100644 index 0000000000000000000000000000000000000000..114387d16e7a585188aedb535fa62b8671d7a7b7 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/loader/FlutterLoader.ets @@ -0,0 +1,219 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * flutterLoader,负责dart虚拟机启动和dart代码加载 + */ +import FlutterShellArgs from '../FlutterShellArgs'; +import FlutterNapi from '../FlutterNapi'; +import Log from '../../../util/Log'; +import FlutterApplicationInfo from './FlutterApplicationInfo'; +import common from '@ohos.app.ability.common'; +import StringUtils from '../../../util/StringUtils'; +import ApplicationInfoLoader from './ApplicationInfoLoader'; +import bundleManager from '@ohos.bundle.bundleManager'; +import fs from '@ohos.file.fs'; + +const TAG = "FlutterLoader"; + +//flutter引擎so +const DEFAULT_LIBRARY = "libflutter.so"; +//jit产物默认kenel文件 +const DEFAULT_KERNEL_BLOB = "kernel_blob.bin"; +//jit产物,默认快照文件 +const VMSERVICE_SNAPSHOT_LIBRARY = "libvmservice_snapshot.so"; +//key值 +const SNAPSHOT_ASSET_PATH_KEY = "snapshot-asset-path"; +//key值 +const VM_SNAPSHOT_DATA_KEY = "vm-snapshot-data"; +//key值 +const ISOLATE_SNAPSHOT_DATA_KEY = "isolate-snapshot-data"; + + +const AOT_SHARED_LIBRARY_NAME = "aot-shared-library-name"; + +const AOT_VMSERVICE_SHARED_LIBRARY_NAME = "aot-vmservice-shared-library-name"; + +//文件路径分隔符 +const FILE_SEPARATOR = "/"; + +/** + * 定位在hap包中的flutter资源,并且加载flutter native library. + */ +export default class FlutterLoader { + flutterNapi: FlutterNapi; + initResult: InitResult; + flutterApplicationInfo: FlutterApplicationInfo; + context: common.Context; + initialized: boolean; + //初始化开始时间戳 + initStartTimestampMillis: number; + + constructor(flutterNapi: FlutterNapi) { + this.flutterNapi = flutterNapi; + } + + /** + * Starts initialization of the native system. + * + *

This loads the Flutter engine's native library to enable subsequent JNI calls. This also + * starts locating and unpacking Dart resources packaged in the app's APK. + * + *

Calling this method multiple times has no effect. + * + * @param applicationContext The Android application context. + * @param settings Configuration settings. + */ + async startInitialization(context: common.Context) { + Log.d(TAG, "flutterLoader start init") + this.initStartTimestampMillis = Date.now(); + this.context = context; + this.flutterApplicationInfo = ApplicationInfoLoader.load(context); + Log.d(TAG, "context.filesDir=" + context.filesDir) + Log.d(TAG, "context.cacheDir=" + context.cacheDir) + Log.d(TAG, "context.bundleCodeDir=" + context.bundleCodeDir) + if (this.flutterApplicationInfo.isDebugMode) { + await this.copyResource(context) + } + this.initResult = new InitResult( + `${context.filesDir}/`, + `${context.cacheDir}/`, + `${context.filesDir}` + ) + Log.d(TAG, "flutterLoader end init") + } + + private async copyResource(context: common.Context) { + let filePath = context.filesDir + FILE_SEPARATOR + this.flutterApplicationInfo.flutterAssetsDir + if (!fs.accessSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB)) { + Log.d(TAG, "start copyResource") + fs.mkdirSync(filePath) + + let icudtlBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + "/icudtl.dat") + let icudtlFile = fs.openSync(filePath + FILE_SEPARATOR + "/icudtl.dat", fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(icudtlFile.fd, icudtlBuffer.buffer) + + let kernelBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB) + let kernelFile = fs.openSync(filePath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(kernelFile.fd, kernelBuffer.buffer) + + let vmBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + this.flutterApplicationInfo.vmSnapshotData) + let vmFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo.vmSnapshotData, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(vmFile.fd, vmBuffer.buffer) + + let isolateBuffer = await this.context.resourceManager.getRawFileContent(this.flutterApplicationInfo.flutterAssetsDir + FILE_SEPARATOR + this.flutterApplicationInfo.isolateSnapshotData) + let isolateFile = fs.openSync(filePath + FILE_SEPARATOR + this.flutterApplicationInfo.isolateSnapshotData, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE) + fs.writeSync(isolateFile.fd, isolateBuffer.buffer) + Log.d(TAG, "copyResource end") + } else { + Log.d(TAG, "no copyResource") + } + } + + /** + * 初始化dart虚拟机方法 + * @param flutterShellArgs + */ + ensureInitializationComplete(shellArgs: Array) { + if (this.initialized) { + return; + } + Log.d(TAG, "ensureInitializationComplete") + if (shellArgs == null) { + shellArgs = new Array(); + } + shellArgs.push( + "--icu-native-lib-path=" + + this.flutterApplicationInfo.nativeLibraryDir + + FILE_SEPARATOR + DEFAULT_LIBRARY + ); + + let kernelPath: string = ""; + if (this.flutterApplicationInfo.isDebugMode) { + Log.d(TAG, "this.initResult.dataDirPath=" + this.initResult.dataDirPath) + const snapshotAssetPath = this.initResult.dataDirPath + FILE_SEPARATOR + this.flutterApplicationInfo.flutterAssetsDir; + kernelPath = snapshotAssetPath + FILE_SEPARATOR + DEFAULT_KERNEL_BLOB; + shellArgs.push("--icu-data-file-path=" + snapshotAssetPath + "/icudtl.dat") + shellArgs.push("--" + SNAPSHOT_ASSET_PATH_KEY + "=" + snapshotAssetPath); + shellArgs.push("--" + VM_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo.vmSnapshotData); + shellArgs.push( + "--" + ISOLATE_SNAPSHOT_DATA_KEY + "=" + this.flutterApplicationInfo.isolateSnapshotData); + } else { + shellArgs.push( + "--" + AOT_SHARED_LIBRARY_NAME + "=" + this.flutterApplicationInfo.aotSharedLibraryName); + shellArgs.push( + "--" + + AOT_SHARED_LIBRARY_NAME + + "=" + + this.flutterApplicationInfo.nativeLibraryDir + + FILE_SEPARATOR + + this.flutterApplicationInfo.aotSharedLibraryName); + if (this.flutterApplicationInfo.isProfile) { + shellArgs.push("--" + AOT_VMSERVICE_SHARED_LIBRARY_NAME + "=" + VMSERVICE_SNAPSHOT_LIBRARY); + } + } + shellArgs.push("--cache-dir-path=" + this.initResult.engineCachesPath); + if (StringUtils.isNotEmpty(this.flutterApplicationInfo.domainNetworkPolicy)) { + shellArgs.push("--domain-network-policy=" + this.flutterApplicationInfo.domainNetworkPolicy); + } + + const resourceCacheMaxBytesThreshold = 1080 * 1920 * 12 * 4; + shellArgs.push("--resource-cache-max-bytes-threshold=" + resourceCacheMaxBytesThreshold); + + shellArgs.push("--prefetched-default-font-manager"); + + shellArgs.push("--leak-vm=" + true); + + //shellArgs.push("--enable-impeller"); + + // //最终初始化操作 + const costTime = Date.now() - this.initStartTimestampMillis; + this.flutterNapi.init( + this.context, + shellArgs, + kernelPath, + this.initResult.appStoragePath, + this.initResult.engineCachesPath, + costTime + ); + this.initialized = true; + } + + findAppBundlePath(): string { + return this.flutterApplicationInfo.flutterAssetsDir; + } + + getLookupKeyForAsset(asset: string, packageName?: string): string { + return this.fullAssetPathFrom(asset); + } + + fullAssetPathFrom(filePath: string): string { + return this.flutterApplicationInfo.flutterAssetsDir + "/" + filePath; + } +} + +class InitResult { + appStoragePath: string; + engineCachesPath: string; + dataDirPath: string; + + constructor(appStoragePath: string, + engineCachesPath: string, + dataDirPath: string) { + this.appStoragePath = appStoragePath; + this.engineCachesPath = engineCachesPath; + this.dataDirPath = dataDirPath; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets new file mode 100644 index 0000000000000000000000000000000000000000..1915bd4afb357fa8f612b688236168f1834abca6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorView.ets @@ -0,0 +1,150 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import ArrayList from '@ohos.util.ArrayList'; +import matrix4 from '@ohos.matrix4'; +import { DVModel, DVModelEvents, DVModelParameters } from '../../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../../view/DynamicView/dynamicViewJson'; +import OhosTouchProcessor from '../../ohos/OhosTouchProcessor'; +import { FlutterMutator, FlutterMutatorsStack } from './FlutterMutatorsStack' + +export class FlutterMutatorView { + private mutatorsStack: FlutterMutatorsStack; + private screenDensity: number; + private left: number; + private top: number; + private prevLeft: number; + private prevTop: number; + private ohosTouchProcessor: OhosTouchProcessor; + private onTouch = (touchEvent: ESObject) => { + let params = this.model.params as Record; + switch (touchEvent.type) { + case TouchType.Down: + this.prevLeft = this.left; + this.prevTop = this.top; + // this.model.params["translateX"] = this.left; + // this.model.params["translateY"] = this.top; + params.translateX = this.left; + params.translateY = this.top; + break; + case TouchType.Move: + // this.model.params["translateX"] = this.prevLeft; + // this.model.params["translateY"] = this.prevTop; + params.translateX = this.prevLeft; + params.translateY = this.prevTop; + this.prevLeft = this.left; + this.prevTop = this.top; + break; + case TouchType.Up: + case TouchType.Cancel: + default: + break; + } + } + + private model: DVModel = createDVModelFromJson( + new DVModelParam("Column", [], { backgroundColor: Color.Red }, { onTouch: this.onTouch }) + ); + + setOnDescendantFocusChangeListener(onFocus: () => void, onBlur: () => void) { + // this.model.events["onFocus"] = onFocus; + // this.model.events["onBlur"] = onBlur; + let events2 = this.model.events as Record; + events2.onFocus = onFocus; + events2.onBlur = onBlur; + } + + public setLayoutParams(parameters: DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + let params = this.model.params as Record | matrix4.Matrix4Transit>; + let parametersRecord = parameters as Record | matrix4.Matrix4Transit>; + // this.model.params['marginLeft'] = parameters['marginLeft']; + // this.model.params['marginTop'] = parameters['marginTop']; + // this.model.params['width'] = parameters['width']; + // this.model.params['height'] = parameters['height']; + params.marginLeft = parametersRecord['marginLeft']; + params.marginTop = parametersRecord['marginTop']; + params.width = parametersRecord['width']; + params.height = parametersRecord['height']; + // this.left = parameters['marginLeft']; + // this.top = parameters['marginTop']; + this.left = parametersRecord.marginLeft as number; + this.top = parametersRecord.marginTop as number ; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } + + public readyToDisplay(mutatorsStack: FlutterMutatorsStack, left: number, top: number, width: number, height: number) { + this.mutatorsStack = mutatorsStack; + this.left = left; + this.top = top; + let parameters = new DVModelParameters() as Record | matrix4.Matrix4Transit>; + parameters['marginLeft'] = left; + parameters['marginTop'] = top; + parameters['width'] = width; + parameters['height'] = height; + this.setLayoutParams(parameters); + this.dealMutators(); + } + + private dealMutators() { + let paths = this.mutatorsStack.getFinalClippingPaths(); + let rects = this.mutatorsStack.getFinalClippingRects(); + let matrix = this.mutatorsStack.getFinalMatrix(); + let params = this.model.params as Record | matrix4.Matrix4Transit>; + if (!paths.isEmpty()) { + let path = paths.getLast(); + // this.model.params["pathWidth"] = path.width; + // this.model.params["pathHeight"] = path.height; + // this.model.params["pathCommands"] = path.commands; + params.pathWidth = path.width; + params.pathHeight = path.height; + params.pathCommands = path.commands; + } + if (!rects.isEmpty()) { + let rect = rects.getLast(); + // this.model.params["rectWidth"] = rect.width; + // this.model.params["rectHeight"] = rect.height; + // this.model.params["rectRadius"] = rect.radius; + params.rectWidth = rect.width; + params.rectHeight = rect.height; + params.rectRadius = rect.radius; + } + // this.model.params["matrix"] = matrix; + params.matrix = matrix; + } + + public getDvModel(): DVModel { + return this.model; + } +} + +class DVModelParam { + compType: string + children: [] + attributes: ESObject + events: ESObject + + constructor(compType: string, children: [], attributes: ESObject, events: ESObject) { + this.compType = compType; + this.children = children; + this.attributes = attributes; + this.events = events; + } +}; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets new file mode 100644 index 0000000000000000000000000000000000000000..59da6edd6c86a74b2db936777ee43ba1df117a69 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/mutatorsstack/FlutterMutatorsStack.ets @@ -0,0 +1,136 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import matrix4 from '@ohos.matrix4' +import List from '@ohos.util.List'; + +export enum FlutterMutatorType { + CLIP_RECT, + CLIP_PATH, + TRANSFORM, + OPACITY +} + +class Rect { + width: number; + height: number; + radius?: string | number | Array; + + constructor(width:number, height:number, radius?:string | number | Array) { + this.width = width; + this.height = height; + this.radius = radius; + } +} + +class Path { + width: number | string; + height: number | string; + commands?: string; + + constructor(width:number | string, height:number | string, commands?:string) { + this.width = width; + this.height = height; + this.commands = commands; + } +} + +export class FlutterMutator { + private matrix: matrix4.Matrix4Transit; + private rect: Rect; + private path: Path; + + constructor(args: matrix4.Matrix4Transit | Rect | Path) { + if (args instanceof Rect) { + this.rect = args; + } else if (args instanceof Path) { + this.path = args; + } else { + this.matrix = args; + } + } + + public getMatrix() { + return this.matrix; + } + + public getRect() { + return this.rect; + } + + public getPath() { + return this.path; + } +} + +export class FlutterMutatorsStack { + private mutators: List; + private finalClippingPaths: List; + private finalClippingRects: List; + + private finalMatrix: matrix4.Matrix4Transit; + + constructor() { + this.mutators = new List(); + this.finalClippingPaths = new List(); + this.finalClippingRects = new List(); + this.finalMatrix = matrix4.identity(); + } + + public pushTransform(values: Array): void { + if (values.length != 16) { + return; + } + let index = 0; + let matrix = matrix4.init( + [values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++], + values[index++], values[index++], values[index++], values[index++]]); + let mutator = new FlutterMutator(matrix); + this.mutators.add(mutator); + this.finalMatrix.combine(matrix); + } + + public pushClipRect(width:number, height:number, radius?:number) { + let rect = new Rect(width, height, radius); + let mutator = new FlutterMutator(rect); + this.mutators.add(mutator); + this.finalClippingRects.add(rect); + } + + public pushClipPath(width:number, height:number, command?:string) { + let path = new Path(width, height, command); + let mutator = new FlutterMutator(path); + this.mutators.add(mutator); + this.finalClippingPaths.add(path); + } + + public getMutators() { + return this.mutators; + } + + public getFinalClippingPaths() { + return this.finalClippingPaths; + } + + public getFinalClippingRects() { + return this.finalClippingRects; + } + + public getFinalMatrix() { + return this.finalMatrix; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..3045e2b8d7ddf48a11d96a642650c63a3f6c0025 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import PlatformViewRegistry from '../../../plugin/platform/PlatformViewRegistry'; +import FlutterEngineGroup from '../FlutterEngineGroup'; + +export interface FlutterPlugin { + //获取唯一的类名 类似安卓的ClassRelevant resources that this {@code FlutterPlugin} may need are provided via the {@code + * binding}. The {@code binding} may be cached and referenced until {@link + * #onDetachedFromEngine(FlutterPluginBinding)} is invoked and returns. + */ + onAttachedToEngine(binding: FlutterPluginBinding): void; + + /** + * This {@code FlutterPlugin} has been removed from a {@link + * io.flutter.embedding.engine.FlutterEngine} instance. + * + *

The {@code binding} passed to this method is the same instance that was passed in {@link + * #onAttachedToEngine(FlutterPluginBinding)}. It is provided again in this method as a + * convenience. The {@code binding} may be referenced during the execution of this method, but it + * must not be cached or referenced after this method returns. + * + *

{@code FlutterPlugin}s should release all resources in this method. + */ + onDetachedFromEngine(binding: FlutterPluginBinding): void; +} + +export class FlutterPluginBinding { + private applicationContext: common.Context; + private binaryMessenger: BinaryMessenger; + private flutterAssets: FlutterAssets; + private group: FlutterEngineGroup; + private platformViewRegistry: PlatformViewRegistry; + + constructor(applicationContext: common.Context, binaryMessenger: BinaryMessenger, flutterAssets: FlutterAssets, group: FlutterEngineGroup, platformViewRegistry?: PlatformViewRegistry) { + this.applicationContext = applicationContext; + this.binaryMessenger = binaryMessenger; + this.flutterAssets = flutterAssets; + this.group = group; + this.platformViewRegistry = platformViewRegistry; + } + + getApplicationContext(): common.Context { + return this.applicationContext; + } + + getBinaryMessenger(): BinaryMessenger { + return this.binaryMessenger; + } + + getFlutterAssets(): FlutterAssets { + return this.flutterAssets; + } + + getEngineGroup(): FlutterEngineGroup { + return this.group; + } + + public getPlatformViewRegistry(): PlatformViewRegistry { + return this.platformViewRegistry; + } +} + +/** Provides Flutter plugins with access to Flutter asset information. */ +export interface FlutterAssets { + /** + * Returns the relative file path to the Flutter asset with the given name, including the file's + * extension, e.g., {@code "myImage.jpg"}. + * + *

The returned file path is relative to the Ohos app's standard assets directory. + * Therefore, the returned path is appropriate to pass to Ohos's {@code ResourceManage}, but + * the path is not appropriate to load as an absolute path. + */ + getAssetFilePathByName(assetFileName: string): string; + + /** + * Same as {@link #getAssetFilePathByName(String)} but with added support for an explicit + * Ohos {@code bundleName}. + */ + getAssetFilePathByName(assetFileName: string, bundleName: string): string; + + /** + * Returns the relative file path to the Flutter asset with the given subpath, including the + * file's extension, e.g., {@code "/dir1/dir2/myImage.jpg"}. + * + *

The returned file path is relative to the Ohos app's standard assets directory. + * Therefore, the returned path is appropriate to pass to Ohos's {@code ResourceManage}, but + * the path is not appropriate to load as an absolute path. + */ + getAssetFilePathBySubpath(assetSubpath: string): string; + + /** + * Same as {@link #getAssetFilePathBySubpath(String)} but with added support for an explicit + * Ohos {@code bundleName}. + */ + getAssetFilePathBySubpath(assetSubpath: string, bundleName: string): string; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..1a322ec2ba1bbcfcbce180b00ec4df6356733180 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/PluginRegistry.ets @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterPlugin } from './FlutterPlugin'; + +export default interface PluginRegistry { + /** + * Attaches the given {@code plugin} to the {@link io.flutter.embedding.engine.FlutterEngine} + * associated with this {@code PluginRegistry}. + */ + add(plugin: FlutterPlugin): void; + + /** + * Attaches the given {@code plugins} to the {@link io.flutter.embedding.engine.FlutterEngine} + * associated with this {@code PluginRegistry}. + */ + addList(plugins: Set): void; + + /** + * Returns true if a plugin of the given type is currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + */ + //Class + has(pluginClassName: string): boolean; + + /** + * Returns the instance of a plugin that is currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}, which + * matches the given {@code pluginClass}. + * + *

If no matching plugin is found, {@code null} is returned. + */ + //Class + get(pluginClassName: string): FlutterPlugin; + + /** + * Detaches the plugin of the given type from the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no such plugin exists, this method does nothing. + */ + //Class + remove(pluginClassName: string): void; + + /** + * Detaches the plugins of the given types from the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no such plugins exist, this method does nothing. + */ + //Class + removeList(pluginClassNames: Set): void; + + /** + * Detaches all plugins that are currently attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} associated with this {@code PluginRegistry}. + * + *

If no plugins are currently attached, this method does nothing. + */ + removeAll(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets new file mode 100644 index 0000000000000000000000000000000000000000..bd68f68aee68859e0c13b696743c8d9d280b7500 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * {@link io.flutter.embedding.engine.plugins.FlutterPlugin} that is interested in {@link + * ohos.app.ability.UIAbility} lifecycle events related to a {@link + * io.flutter.embedding.engine.FlutterEngine} running within the given {@link ohos.app.ability.UIAbility}. + */ +import { AbilityPluginBinding } from './AbilityPluginBinding'; + +export default interface AbilityAware { + /** + * This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} is now + * associated with an {@link ohos.app.ability.UIAbility}. + * + *

This method can be invoked in 1 of 2 situations: + * + *

    + *
  • This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} was + * just added to a {@link io.flutter.embedding.engine.FlutterEngine} that was already + * connected to a running {@link ohos.app.ability.UIAbility}. + *
  • This {@code AbilityAware} {@link io.flutter.embedding.engine.plugins.FlutterPlugin} was + * already added to a {@link io.flutter.embedding.engine.FlutterEngine} and that {@link + * io.flutter.embedding.engine.FlutterEngine} was just connected to an {@link + * ohos.app.ability.UIAbility}. + *
+ * + * The given {@link AbilityPluginBinding} contains {@link ohos.app.ability.UIAbility}-related + * references that an {@code AbilityAware} {@link + * io.flutter.embedding.engine.plugins.FlutterPlugin} may require, such as a reference to the + * actual {@link ohos.app.ability.UIAbility} in question. The {@link AbilityPluginBinding} may be + * referenced until either {@link #onDetachedFromAbilityForConfigChanges()} or {@link + * #onDetachedFromAbility()} is invoked. At the conclusion of either of those methods, the + * binding is no longer valid. Clear any references to the binding or its resources, and do not + * invoke any further methods on the binding or its resources. + */ + onAttachedToAbility(binding: AbilityPluginBinding): void ; + + /** + * This plugin has been detached from an {@link ohos.app.ability.UIAbility}. + * + *

Detachment can occur for a number of reasons. + * + *

    + *
  • The app is no longer visible and the {@link ohos.app.ability.UIAbility} instance has been + * destroyed. + *
  • The {@link io.flutter.embedding.engine.FlutterEngine} that this plugin is connected to + * has been detached from its {@link io.flutter.embedding.android.FlutterView}. + *
  • This {@code AbilityAware} plugin has been removed from its {@link + * io.flutter.embedding.engine.FlutterEngine}. + *
+ * + * By the end of this method, the {@link ohos.app.ability.UIAbility} that was made available in {@link + * #onAttachedToAbility(AbilityPluginBinding)} is no longer valid. Any references to the + * associated {@link ohos.app.ability.UIAbility} or {@link AbilityPluginBinding} should be cleared. + * + *

Any {@code Lifecycle} listeners that were registered in {@link + * #onAttachedToAbility(AbilityPluginBinding)} or {@link + * #onReattachedToAbilityForConfigChanges(AbilityPluginBinding)} should be deregistered here to + * avoid a possible memory leak and other side effects. + */ + onDetachedFromAbility(): void; +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets new file mode 100644 index 0000000000000000000000000000000000000000..cdc25248736f45b41fa4752c386522de4fa3759c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityControlSurface.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import Want from '@ohos.app.ability.Want'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from '../../../ohos/ExclusiveAppComponent'; + +export default interface ActivityControlSurface { + attachToAbility(exclusiveActivity: ExclusiveAppComponent): void; + detachFromAbility(): void; + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; + onWindowFocusChanged(hasFocus: boolean): void; + // onSaveState(reason: AbilityConstant.StateType, wantParam: { [key: string]: Object; }): AbilityConstant.OnSaveResult; + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets new file mode 100644 index 0000000000000000000000000000000000000000..9195e2f8f325596759a756dfdb93dc69a27b3e9e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility' +import Want from '@ohos.app.ability.Want'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; + +export interface AbilityPluginBinding { + getAbility(): UIAbility; + /** + * Adds a listener that is invoked whenever the associated {@link ohos.app.ability.UIAbility}'s {@code + * onNewWant(...)} method is invoked. + */ + addOnNewWantListener(listener: NewWantListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnNewWantListener(NewWantListener)}. + */ + removeOnNewWantListener(listener: NewWantListener): void; + + /** + * Adds a listener that is invoked whenever the associated {@link ohos.app.ability.UIAbility}'s {@code + * windowStageEvent} method is invoked. + */ + addOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnWindowFocusChangedListener(WindowFocusChangedListener)}. + */ + removeOnWindowFocusChangedListener(listener: WindowFocusChangedListener): void; + + /** + * Adds a listener that is invoked when the associated {@code UIAbility} saves + * and restores instance state. + */ + addOnSaveStateListener(listener: OnSaveStateListener): void; + + /** + * Removes a listener that was added in {@link + * #addOnSaveStateListener(OnSaveStateListener)}. + */ + removeOnSaveStateListener(listener: OnSaveStateListener): void; +} + +/** + * Delegate interface for handling new wants on behalf of the main {@link ohos.app.ability.UIAbility}. + */ +export interface NewWantListener { + /** + * @param intent The new want that was started for the UIAbility. + * @return true if the new want has been handled. + */ + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void; +} + +/** + * Delegate interface for handling window focus changes on behalf of the main {@link + * ohos.app.ability.UIAbility}. + */ +export interface WindowFocusChangedListener { + onWindowFocusChanged(hasFocus: boolean): void; +} + +export interface OnSaveStateListener { + /** + * Invoked when the associated {@code UIAbility} or {@code Fragment} executes {@link + * Activity#onSaveState(Bundle)}. + */ + // onSaveState(reason: AbilityConstant.StateType, wantParam: { [key: string]: Object; }): AbilityConstant.OnSaveResult; + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets new file mode 100644 index 0000000000000000000000000000000000000000..2a0af4009cafd2cf5229f082a41ed2d445c69caa --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/renderer/FlutterUiDisplayListener.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export interface FlutterUiDisplayListener { + onFlutterUiDisplayed(): void; + + onFlutterUiNoLongerDisplayed(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..ed96f236fb55a878ef4b03766a7751cf389e377a --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/AccessibilityChannel.ets @@ -0,0 +1,118 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +import BasicMessageChannel, { MessageHandler, Reply} from '../../../plugin/common/BasicMessageChannel'; +import HashMap from '@ohos.util.HashMap'; +import FlutterNapi, {AccessibilityDelegate} from '../FlutterNapi'; +import { Action } from '../../../view/AccessibilityBridge' +import StandardMessageCodec from '../../../plugin/common/StandardMessageCodec'; + +/** +* 辅助功能channel +*/ +export default class AccessibilityChannel implements MessageHandler{ + private static TAG = "AccessibilityChannel"; + private static CHANNEL_NAME = "flutter/accessibility"; + private channel: BasicMessageChannel; + private flutterNapi: FlutterNapi; + private handler: AccessibilityMessageHandler; + private nextReplyId: number = 1; + + onMessage(message: object, reply: Reply): void { + if (this.handler == null) { + Log.i(AccessibilityChannel.TAG, "NULL"); + reply.reply(null); + return; + } + let annotatedEvent: HashMap = message as HashMap; + let type: string = annotatedEvent.get("type") as string; + let data: HashMap = annotatedEvent.get("data") as HashMap; + + Log.i(AccessibilityChannel.TAG, "Received " + type + " message."); + switch (type) { + case "announce": { + Log.i(AccessibilityChannel.TAG, "Announce"); + let announceMessage: string = data.get("message"); + if (announceMessage != null) { + this.handler.announce(announceMessage); + } + break; + } + case "tap": { + Log.i(AccessibilityChannel.TAG, "Tag"); + let nodeId: number = annotatedEvent.get("nodeId"); + if (nodeId != null) { + this.handler.onTap(nodeId); + } + break; + } + case "longPress": { + Log.i(AccessibilityChannel.TAG, "LongPress"); + let nodeId: number = annotatedEvent.get("nodeId"); + if (nodeId != null) { + this.handler.onLongPress(nodeId); + } + break; + } + case "tooltip": { + Log.i(AccessibilityChannel.TAG, "ToolTip"); + let tooltipMessage: string = data.get("message"); + if (tooltipMessage != null) { + this.handler.onTooltip(tooltipMessage); + } + break; + } + } + reply.reply(null); + } + + constructor(dartExecutor: DartExecutor, flutterNapi: FlutterNapi) { + Log.i(AccessibilityChannel.TAG, "Channel entered"); + this.channel = new BasicMessageChannel(dartExecutor, AccessibilityChannel.CHANNEL_NAME, StandardMessageCodec.INSTANCE); + this.channel.setMessageHandler(this); + this.flutterNapi = flutterNapi; + } + + onOhosAccessibilityEnabled(): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.setSemanticsEnabled(true, replyId); + } + + onOhosAccessibilityFeatures(accessibilityFeatureFlags: number): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.setAccessibilityFeatures(accessibilityFeatureFlags, replyId); + } + + dispatchSemanticsAction(virtualViewId: number, action: Action): void { + let replyId: number = this.nextReplyId++; + this.flutterNapi.dispatchSemanticsAction(virtualViewId, action, replyId); + } + + setAccessibilityMessageHandler(handler: AccessibilityMessageHandler): void { + this.handler = handler; + let replyId: number = this.nextReplyId++; + this.flutterNapi.setAccessibilityDelegate(handler, replyId); + } + +} + +interface AccessibilityMessageHandler extends AccessibilityDelegate { + announce(message: string): void; + onTap(nodeId: number): void; + onLongPress(nodeId: number): void; + onTooltip(nodeId: string): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..8ac0e08bf3da27a8a14a8e83c47099184ba63945 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/KeyEventChannel.ets @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../../../plugin/common/BinaryMessenger'; +import { Reply } from '../../../plugin/common/BasicMessageChannel'; +import { Action, Key, KeyEvent } from '@ohos.multimodalInput.keyEvent'; +import Log from '../../../util/Log'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; + +export default class KeyEventChannel { + private static TAG = "KeyEventChannel"; + private static CHANNEL_NAME = "flutter/keyevent"; + private channel : BasicMessageChannel>; + + constructor(binaryMessenger: BinaryMessenger) { + this.channel = new BasicMessageChannel>(binaryMessenger, KeyEventChannel.CHANNEL_NAME, JSONMessageCodec.INSTANCE); + } + + sendFlutterKeyEvent(keyEvent: FlutterKeyEvent, + isKeyUp: boolean, + responseHandler: EventResponseHandler): void { + this.channel.send(this.encodeKeyEvent(keyEvent, isKeyUp), + (message:Map) => { + let isEventHandled = false; + try { + if (message != null) { + isEventHandled = message.get("handled") as boolean; + } + } catch (e) { + Log.e(KeyEventChannel.TAG, "Unable to unpack JSON message: " + e); + } + responseHandler.onFrameworkResponse(isEventHandled); + } + ); + } + + encodeKeyEvent(keyEvent: FlutterKeyEvent, isKeyUp: boolean): Map { + let message: Map = new Map(); + message.set("type", isKeyUp ? "keyup" : "keydown"); + message.set("keymap", "ohos"); + message.set("codePoint", keyEvent.event.unicodeChar); + message.set("keyCode", keyEvent.event.key.code); + message.set("deviceId", keyEvent.event.key.deviceId); + message.set("character", keyEvent.event.key.code.toString()); + message.set("repeatCount", 1); + return message; + } + + +} + +export interface EventResponseHandler { + onFrameworkResponse(isEventHandled: boolean): void; +} + +export class FlutterKeyEvent { + event: KeyEvent; + + constructor( ohosKeyEvent: KeyEvent) { + this.event = ohosKeyEvent; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..ce5acbdbbae50078e7c339c767a34a178413bf2d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LifecycleChannel.ets @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../../util/Log'; +import StringCodec from '../../../plugin/common/StringCodec'; +import DartExecutor from '../dart/DartExecutor'; +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; + +/** + * 生命周期channel + */ +export default class LifecycleChannel { + private static TAG = "LifecycleChannel"; + private static CHANNEL_NAME = "flutter/lifecycle"; + + // These should stay in sync with the AppLifecycleState enum in the framework. + private static RESUMED = "AppLifecycleState.resumed"; + private static INACTIVE = "AppLifecycleState.inactive"; + private static PAUSED = "AppLifecycleState.paused"; + private static DETACHED = "AppLifecycleState.detached"; + + private lastOhosState = ""; + private lastFlutterState = ""; + private lastFocus = true; + + private channel: BasicMessageChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, LifecycleChannel.CHANNEL_NAME, StringCodec.INSTANCE) + } + + // Called if at least one window in the app has focus. + aWindowIsFocused(): void { + this.sendState(this.lastOhosState, true); + } + + // Called if no windows in the app have focus. + noWindowsAreFocused(): void { + this.sendState(this.lastOhosState, false); + } + + appIsResumed(): void { + this.sendState(LifecycleChannel.RESUMED, this.lastFocus); + } + + appIsInactive(): void { + this.sendState(LifecycleChannel.INACTIVE, this.lastFocus); + } + + appIsPaused(): void { + this.sendState(LifecycleChannel.PAUSED, this.lastFocus); + } + + appIsDetached(): void { + this.sendState(LifecycleChannel.DETACHED, this.lastFocus); + } + + // Here's the state table this implements: + // + // | UIAbility State | Window focused | Flutter state | + // |-----------------|----------------|---------------| + // | onCreate | true | resumed | + // | onCreate | false | inactive | + // | onForeground | true | resumed | + // | onForeground | false | inactive | + // | onBackground | true | paused | + // | onBackground | false | paused | + // | onDestroy | true | detached | + // | onDestroy | false | detached | + + private sendState(state: string, hasFocus: boolean): void { + if (this.lastOhosState == state && hasFocus == this.lastFocus) { + // No inputs changed, so Flutter state could not have changed. + return; + } + let newState: string; + if (state == LifecycleChannel.RESUMED) { + newState = hasFocus ? LifecycleChannel.RESUMED : LifecycleChannel.INACTIVE; + } else { + newState = state; + } + // Keep the last reported values for future updates. + this.lastOhosState = state; + this.lastFocus = hasFocus; + if (newState == this.lastFlutterState) { + // No change in the resulting Flutter state, so don't report anything. + return; + } + Log.i(LifecycleChannel.TAG, "Sending " + newState + " message."); + this.channel.send(newState); + this.lastFlutterState = newState; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..c4b5b6cf7b8868145424897851dd734d7eff5b6a --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/LocalizationChannel.ets @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import DartExecutor from '../dart/DartExecutor'; +import MethodChannel, { MethodCallHandler, MethodResult} from '../../../plugin/common/MethodChannel'; +import MethodCall from '../../../plugin/common/MethodCall'; +import List from '@ohos.util.List'; +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import intl from '@ohos.intl'; +import Log from '../../../util/Log'; + +const TAG = "LocalizationChannel"; +export default class LocalizationChannel implements MethodCallHandler{ + private static TAG = "LocalizationChannel"; + private static CHANNEL_NAME = "flutter/localization"; + private channel: MethodChannel; + private localizationMessageHandler: LocalizationMessageHandler; + + onMethodCall(call: MethodCall, result: MethodResult) :void { + if (this.localizationMessageHandler == null) { + Log.e(TAG, "localizationMessageHandler is null"); + return; + } + let method: string = call.method; + switch (method) { + case "Localization.getStringResource": { + Log.i(TAG, "Localization.getStringResource enter"); + let key: string = call.argument("key"); + let localeString: string = null; + if (call.hasArgument("locale")) { + localeString = call.argument("locale"); + } + result.success(this.localizationMessageHandler.getStringResource(key, localeString)); + break; + } + default: { + result.notImplemented(); + break; + } + } + } + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, LocalizationChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + this.channel.setMethodCallHandler(this); + } + + setLocalizationMessageHandler(localizationMessageHandler: LocalizationMessageHandler): void { + this.localizationMessageHandler = localizationMessageHandler; + } + + sendLocales(locales: Array): void { + this.channel.invokeMethod("setLocale", locales); + } +} + +export interface LocalizationMessageHandler { + getStringResource(key: string, local: string); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..210a7510a478d350cd38e89d7826e3a53290dfa8 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/MouseCursorChannel.ets @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG:string = 'MouseCursorChannel' + +export default class MouseCursorChannel implements MethodCallHandler { + public channel: MethodChannel; + + private mouseCursorMethodHandler: MouseCursorMethodHandler; + + onMethodCall(call: MethodCall, result: MethodResult): void { + if (this.mouseCursorMethodHandler === null) { + // if no explicit mouseCursorMethodHandler has been registered then we don't + // need to formed this call to an API. Return + Log.e(TAG, "mouseCursorMethodHandler is null") + return; + } + + let method: string = call.method; + Log.i(TAG, "Received '" + method + "' message."); + try { + // More methods are expected to be added here, hence the switch. + switch (method) { + case "activateSystemCursor": + let argument: HashMap = call.args; + let kind: string = argument.get("kind"); + try { + this.mouseCursorMethodHandler.activateSystemCursor(kind); + } catch (err) { + result.error("error", "Error when setting cursors: " + JSON.stringify(err), null); + break; + } + result.success(true); + break; + default: + break; + } + } catch (error) { + result.error("error", "UnHandled error: " + JSON.stringify(error), null) + } + } + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/mousecursor", StandardMethodCodec.INSTANCE); + this.channel.setMethodCallHandler(this); + } + + /** + * Sets the {@link MouseCursorMethodHandler} which receives all events and requests that are + * parsed from the underlying platform channel. + * @param mouseCursorMethodHandler + */ + public setMethodHandler(mouseCursorMethodHandler: MouseCursorMethodHandler): void { + this.mouseCursorMethodHandler = mouseCursorMethodHandler; + } + + public synthesizeMethodCall(call: MethodCall, result: MethodResult): void { + this.onMethodCall(call, result); + } +} + +export interface MouseCursorMethodHandler { + // Called when the pointer should start displaying a system mouse cursor + // specified by {@code shapeCode}. + activateSystemCursor(kind: String): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ebcb6926eb490ed2ee21cb8927e5ed2a202632 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/NavigationChannel.ets @@ -0,0 +1,62 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +export default class NavigationChannel { + private static TAG = "NavigationChannel"; + private channel: MethodChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/navigation", JSONMethodCodec.INSTANCE); + // Provide a default handler that returns an empty response to any messages + // on this channel. + this.channel.setMethodCallHandler(new NavigationCallback()); + } + + setInitialRoute(initialRoute: string): void { + Log.i(NavigationChannel.TAG, "Sending message to set initial route to '" + initialRoute + "'"); + this.channel.invokeMethod("setInitialRoute", initialRoute); + } + + pushRoute(route: string): void { + Log.i(NavigationChannel.TAG, "Sending message to push route '" + route + "'"); + this.channel.invokeMethod("pushRoute", route); + } + + pushRouteInformation(route: string): void { + Log.i(NavigationChannel.TAG, "Sending message to push route information '" + route + "'"); + this.channel.invokeMethod("pushRouteInformation", new Map().set("location", route) ); + } + + popRoute(): void { + Log.i(NavigationChannel.TAG, "Sending message to pop route."); + this.channel.invokeMethod("popRoute", null); + } + + setMethodCallHandler(handler: MethodCallHandler) { + this.channel.setMethodCallHandler(handler); + } +} + +class NavigationCallback implements MethodCallHandler { + onMethodCall(call: MethodCall, result: MethodResult) { + result.success(null); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..20e8db4b44690fd0e2bafbde4044a1f0724fba7f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformChannel.ets @@ -0,0 +1,505 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +import pasteboard from '@ohos.pasteboard'; +import bundleManager from '@ohos.bundle.bundleManager'; +import window from '@ohos.window'; + +export default class PlatformChannel { + private static TAG = "PlatformChannel"; + private static CHANNEL_NAME = "flutter/platform"; + channel: MethodChannel; + platformMessageHandler: PlatformMessageHandler; + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, PlatformChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + let callback = new PlatformMethodCallback(); + callback.platform = this; + this.channel.setMethodCallHandler(callback); + } + + setPlatformMessageHandler(platformMessageHandler: PlatformMessageHandler): void { + this.platformMessageHandler = platformMessageHandler; + } + + systemChromeChanged(overlaysAreVisible: boolean): void { + Log.d(PlatformChannel.TAG, "Sending 'systemUIChange' message."); + this.channel.invokeMethod("SystemChrome.systemUIChange", [overlaysAreVisible]); + } + + decodeOrientations(encodedOrientations: string[]): number { + let requestedOrientation = 0x00; + let firstRequestedOrientation = 0x00; + for(let index = 0; index< encodedOrientations.length; index += 1) { + let encodedOrientation = encodedOrientations[index]; + Log.d(PlatformChannel.TAG,"encodedOrientation[" + index + "]: "+encodedOrientation); + let orientation = this.getDeviceOrientationFromValue(encodedOrientation); + switch (orientation) { + case DeviceOrientation.PORTRAIT_UP: + requestedOrientation |= 0x01; + break; + case DeviceOrientation.PORTRAIT_DOWN: + requestedOrientation |= 0x04; + break; + case DeviceOrientation.LANDSCAPE_LEFT: + requestedOrientation |= 0x02; + break; + case DeviceOrientation.LANDSCAPE_RIGHT: + requestedOrientation |= 0x08; + break; + } + if (firstRequestedOrientation == 0x00) { + firstRequestedOrientation = requestedOrientation; + } + } + + switch (requestedOrientation) { + case 0x00: + return window.Orientation.UNSPECIFIED; + case 0x01: + return window.Orientation.PORTRAIT; + case 0x02: + return window.Orientation.LANDSCAPE; + case 0x03: + case 0x04: + return window.Orientation.PORTRAIT_INVERTED; + case 0x05: + return window.Orientation.AUTO_ROTATION_PORTRAIT; + case 0x06: + case 0x07: + case 0x08: + return window.Orientation.LANDSCAPE_INVERTED; + case 0x09: + case 0x0a: + return window.Orientation.AUTO_ROTATION_LANDSCAPE; + case 0x0b: + return window.Orientation.LOCKED; + case 0x0c: + case 0x0d: + case 0x0e: + switch (firstRequestedOrientation) { + case 0x01: + return bundleManager.DisplayOrientation.PORTRAIT; + case 0x02: + return bundleManager.DisplayOrientation.LANDSCAPE; + case 0x04: + return bundleManager.DisplayOrientation.PORTRAIT_INVERTED; + case 0x08: + return bundleManager.DisplayOrientation.LANDSCAPE_INVERTED; + } + case 0x0f: + } + return bundleManager.DisplayOrientation.PORTRAIT; + } + + getFeedbackTypeFromValue(encodedName: string): HapticFeedbackType { + if (encodedName == null) { + return HapticFeedbackType.STANDARD; + } + let feedbackTypes: string[] = [ + HapticFeedbackType.STANDARD, + HapticFeedbackType.LIGHT_IMPACT, + HapticFeedbackType.MEDIUM_IMPACT, + HapticFeedbackType.HEAVY_IMPACT, + HapticFeedbackType.SELECTION_CLICK + ]; + for (let i = 0; i < feedbackTypes.length; i++) { + let feedbackType: string = feedbackTypes[i]; + if ( + (HapticFeedbackType[feedbackType] == encodedName) || + (HapticFeedbackType[feedbackType] == null && encodedName == null) + ) { + return HapticFeedbackType[feedbackType]; + } + } + Log.e(PlatformChannel.TAG, "No such HapticFeedbackType:" + encodedName); + } + + getClipboardContentFormatFromValue(encodedName: string): ClipboardContentFormat { + let clipboardFormats : string[]= [ClipboardContentFormat.PLAIN_TEXT]; + for (let i = 0; i < clipboardFormats.length; i++) { + let format = clipboardFormats[i]; + if (ClipboardContentFormat[format] === encodedName) { + return ClipboardContentFormat[format]; + } + } + } + getSystemUiOverlayFromValue(encodedName: string): SystemUiOverlay { + let systemUiOverlays : string[] = [SystemUiOverlay.TOP_OVERLAYS, SystemUiOverlay.BOTTOM_OVERLAYS]; + for (let i = 0; i < systemUiOverlays.length; i++) { + let overlay = systemUiOverlays[i]; + if (SystemUiOverlay[overlay] === encodedName) { + return SystemUiOverlay[overlay]; + } + } + throw new Error("No such SystemUiOverlay: " + encodedName); + } + + getSystemUiModeFromValue(encodedName: string): SystemUiMode { + let systemUiModes : string[] = [ + SystemUiMode.LEAN_BACK, SystemUiMode.IMMERSIVE, + SystemUiMode.IMMERSIVE_STICKY, SystemUiMode.EDGE_TO_EDGE + ]; + for (let i = 0; i < systemUiModes.length; i++) { + let mode = systemUiModes[i]; + if (SystemUiMode[mode] === encodedName) { + return SystemUiMode[mode]; + } + } + throw new Error("No such SystemUiOverlay: " + encodedName); + } + + getBrightnessFromValue(encodedName: string): Brightness { + let brightnesses : string[] = [Brightness.LIGHT, Brightness.DARK]; + for (let i = 0; i < brightnesses.length; i++) { + let brightness = brightnesses[i]; + if (Brightness[brightness] === encodedName) { + return Brightness[brightness]; + } + } + throw new Error("No such Brightness: " + encodedName); + } + + getDeviceOrientationFromValue(encodedName: string): DeviceOrientation { + let deviceOrientations: string[] = [ + DeviceOrientation.PORTRAIT_UP, DeviceOrientation.PORTRAIT_DOWN, + DeviceOrientation.LANDSCAPE_LEFT, DeviceOrientation.LANDSCAPE_RIGHT + ]; + for (let i = 0; i < deviceOrientations.length; i++) { + let orientation = deviceOrientations[i]; + if (DeviceOrientation[orientation] === encodedName) { + return DeviceOrientation[orientation]; + } + } + throw new Error("No such DeviceOrientation: " + encodedName); + } + +} + +export enum HapticFeedbackType { + STANDARD = "STANDARD", + LIGHT_IMPACT = "HapticFeedbackType.lightImpact", + MEDIUM_IMPACT = "HapticFeedbackType.mediumImpact", + HEAVY_IMPACT = "HapticFeedbackType.heavyImpact", + SELECTION_CLICK = "HapticFeedbackType.selectionClick" +} + +export interface PlatformMessageHandler { + playSystemSound(soundType: SoundType): void; + + vibrateHapticFeedback(feedbackType: HapticFeedbackType): void; + + setPreferredOrientations(ohosOrientation: number): void; + + setApplicationSwitcherDescription(description: AppSwitcherDescription): void; + + showSystemOverlays(overlays: SystemUiOverlay[]): void; + + showSystemUiMode(mode: SystemUiMode): void; + + setSystemUiChangeListener(): void; + + restoreSystemUiOverlays(): void; + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle): void; + + popSystemNavigator(): void; + + getClipboardData(format: ClipboardContentFormat): string; + + setClipboardData(text: string): void; + + clipboardHasStrings(): boolean; +} + +export enum ClipboardContentFormat { + PLAIN_TEXT = "text/plain", +} + +export enum SoundType { + CLICK = "SystemSoundType.click", + ALERT = "SystemSoundType.alert", +} + +export class AppSwitcherDescription { + public readonly color: number; + public readonly label: string; + + constructor(color: number, label: string) { + this.color = color; + this.label = label; + } +} + +export enum SystemUiOverlay { + TOP_OVERLAYS = "SystemUiOverlay.top", + BOTTOM_OVERLAYS = "SystemUiOverlay.bottom", +} + +export enum SystemUiMode { + LEAN_BACK = "SystemUiMode.leanBack", + IMMERSIVE = "SystemUiMode.immersive", + IMMERSIVE_STICKY = "SystemUiMode.immersiveSticky", + EDGE_TO_EDGE = "SystemUiMode.edgeToEdge", +} + +export enum Brightness { + LIGHT = "Brightness.light", + DARK = "Brightness.dark", +} + +export class SystemChromeStyle { + public readonly statusBarColor: number | null; + public readonly statusBarIconBrightness: Brightness | null; + public readonly systemStatusBarContrastEnforced: boolean | null; + public readonly systemNavigationBarColor: number | null; + public readonly systemNavigationBarIconBrightness: Brightness | null; + public readonly systemNavigationBarDividerColor: number | null; + public readonly systemNavigationBarContrastEnforced: boolean | null; + + constructor(statusBarColor: number | null, + statusBarIconBrightness: Brightness | null, + systemStatusBarContrastEnforced: boolean | null, + systemNavigationBarColor: number | null, + systemNavigationBarIconBrightness: Brightness | null, + systemNavigationBarDividerColor: number | null, + systemNavigationBarContrastEnforced: boolean | null) { + this.statusBarColor = statusBarColor; + this.statusBarIconBrightness = statusBarIconBrightness; + this.systemStatusBarContrastEnforced = systemStatusBarContrastEnforced; + this.systemNavigationBarColor = systemNavigationBarColor; + this.systemNavigationBarIconBrightness = systemNavigationBarIconBrightness; + this.systemNavigationBarDividerColor = systemNavigationBarDividerColor; + this.systemNavigationBarContrastEnforced = systemNavigationBarContrastEnforced; + } +} + +enum DeviceOrientation { + PORTRAIT_UP = "DeviceOrientation.portraitUp", + PORTRAIT_DOWN = "DeviceOrientation.portraitDown", + LANDSCAPE_LEFT = "DeviceOrientation.landscapeLeft", + LANDSCAPE_RIGHT = "DeviceOrientation.landscapeRight", +} + +class PlatformMethodCallback implements MethodCallHandler { + private static TAG = "PlatformMethodCallback" + platform: PlatformChannel; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.platform.platformMessageHandler == null) { + Log.w(PlatformMethodCallback.TAG, "platformMessageHandler is null"); + return; + } + + let method: string = call.method; + let args: ESObject = call.args; + Log.d(PlatformMethodCallback.TAG, "Received '" + method + "' message."); + try { + switch (method) { + case "SystemSound.play": + break; + case "HapticFeedback.vibrate": + try { + Log.d(PlatformMethodCallback.TAG, "HapticFeedback: " + args as string); + let feedbackType: HapticFeedbackType = this.platform.getFeedbackTypeFromValue(args as string); + this.platform.platformMessageHandler.vibrateHapticFeedback(feedbackType); + result.success(null); + } catch (e) { + Log.e(PlatformMethodCallback.TAG, "HapticFeedback.vibrate error:" + JSON.stringify(e)); + } + break; + case "SystemChrome.setPreferredOrientations": + Log.d(PlatformMethodCallback.TAG, "setPreferredOrientations: " + JSON.stringify(args)); + try { + let ohosOrientation = this.platform.decodeOrientations(args as string[]); + this.platform.platformMessageHandler.setPreferredOrientations(ohosOrientation); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setPreferredOrientations err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + + break; + case "SystemChrome.setApplicationSwitcherDescription": + Log.d(PlatformMethodCallback.TAG, "setApplicationSwitcherDescription: " + JSON.stringify(args)); + break; + case "SystemChrome.setEnabledSystemUIOverlays": + try { + let overlays: SystemUiOverlay[] = this.decodeSystemUiOverlays(args); + Log.d(PlatformMethodCallback.TAG, "overlays: " + overlays); + this.platform.platformMessageHandler.showSystemOverlays(overlays); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIOverlays err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemChrome.setEnabledSystemUIMode": + try { + Log.d(PlatformMethodCallback.TAG, "setEnabledSystemUIMode args:" + args as string); + let mode: SystemUiMode = this.decodeSystemUiMode(args as string) + this.platform.platformMessageHandler.showSystemUiMode(mode); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setEnabledSystemUIMode err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemChrome.setSystemUIChangeListener": + this.platform.platformMessageHandler.setSystemUiChangeListener(); + result.success(null); + break; + case "SystemChrome.restoreSystemUIOverlays": + this.platform.platformMessageHandler.restoreSystemUiOverlays(); + result.success(null); + break; + case "SystemChrome.setSystemUIOverlayStyle": + try { + Log.d(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle asrgs: " + JSON.stringify(args)); + let systemChromeStyle: SystemChromeStyle = this.decodeSystemChromeStyle(args); + this.platform.platformMessageHandler.setSystemUiOverlayStyle(systemChromeStyle); + result.success(null); + } catch (err) { + Log.e(PlatformMethodCallback.TAG, "setSystemUIOverlayStyle err:" + JSON.stringify(err)); + result.error("error", JSON.stringify(err), null); + } + break; + case "SystemNavigator.pop": + this.platform.platformMessageHandler.popSystemNavigator(); + result.success(null); + break; + case "Clipboard.getData": + let pasteBoard = pasteboard.getSystemPasteboard(); + pasteBoard.getData().then((pasteData) => { + let text = pasteData.getPrimaryText(); + let response: ESObject = new Map().set("text", ""); + response.text = text; + result.success(response); + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "Failed to get PasteData. Cause: " + JSON.stringify(err)); + }); + break; + case "Clipboard.setData": + let clipboardContent: string = args.text; + this.platform.platformMessageHandler.setClipboardData(clipboardContent); + result.success(null); + break; + case "Clipboard.hasStrings": + let hasStrings: boolean = false; + let response: ESObject = new Map().set("value", false); + let systemPasteboard = pasteboard.getSystemPasteboard(); + systemPasteboard.hasData().then((hasData) => { + if (!hasData) { + response.value = hasData; + result.success(response); + } + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "systemPasteboard.hasData err: " + JSON.stringify(err)); + }) + systemPasteboard.getData().then((pasteData) => { + hasStrings = pasteData.hasType(pasteboard.MIMETYPE_TEXT_PLAIN); + response.value = hasStrings; + result.success(response); + }).catch((err: ESObject) => { + Log.e(PlatformMethodCallback.TAG, "getData err: " + JSON.stringify(err)); + }) + break; + default: + result.notImplemented(); + break; + } + } catch (e) { + result.error("error", JSON.stringify(e), null); + } + } + + private decodeSystemUiOverlays(encodedSystemUiOverlay: string[]): SystemUiOverlay[] { + let overlays: SystemUiOverlay[] = []; + for(let i = 0; i < encodedSystemUiOverlay.length; i++) { + const encodedOverlay = encodedSystemUiOverlay[i]; + const overlay = this.platform.getSystemUiOverlayFromValue(encodedOverlay); + switch (overlay) { + case SystemUiOverlay.TOP_OVERLAYS: + overlays.push(SystemUiOverlay.TOP_OVERLAYS); + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + overlays.push(SystemUiOverlay.BOTTOM_OVERLAYS); + break; + } + } + return overlays; + } + + private decodeSystemUiMode(encodedSystemUiMode: string): SystemUiMode { + let mode: SystemUiMode = this.platform.getSystemUiModeFromValue(encodedSystemUiMode); + switch (mode) { + case SystemUiMode.LEAN_BACK: + return SystemUiMode.LEAN_BACK; + case SystemUiMode.IMMERSIVE: + return SystemUiMode.IMMERSIVE; + case SystemUiMode.IMMERSIVE_STICKY: + return SystemUiMode.IMMERSIVE_STICKY; + case SystemUiMode.EDGE_TO_EDGE: + default: + return SystemUiMode.EDGE_TO_EDGE; + } + } + + private decodeSystemChromeStyle(encodedStyle: ESObject): SystemChromeStyle { + let statusBarColor: number = null; + let statusBarIconBrightness: Brightness = null; + let systemStatusBarContrastEnforced: boolean = null; + let systemNavigationBarColor: number = null; + let systemNavigationBarIconBrightness: Brightness = null; + let systemNavigationBarDividerColor: number = null; + let systemNavigationBarContrastEnforced: boolean = null; + if(encodedStyle.statusBarColor != null) { + statusBarColor = encodedStyle.statusBarColor as number; + } + if(encodedStyle.statusBarIconBrightness != null) { + statusBarIconBrightness = + this.platform.getBrightnessFromValue(encodedStyle.statusBarIconBrightness as string); + } + if(encodedStyle.systemStatusBarContrastEnforced != null) { + systemStatusBarContrastEnforced = encodedStyle.systemStatusBarContrastEnforced as boolean; + } + if(encodedStyle.systemNavigationBarColor != null) { + systemNavigationBarColor = encodedStyle.systemNavigationBarColor as number; + } + if(encodedStyle.systemNavigationBarIconBrightness != null) { + systemNavigationBarIconBrightness = + this.platform.getBrightnessFromValue(encodedStyle.systemNavigationBarIconBrightness as string); + } + if(encodedStyle.systemNavigationBarDividerColor != null) { + systemNavigationBarDividerColor = encodedStyle.systemNavigationBarDividerColor as number; + } + if(encodedStyle.systemNavigationBarContrastEnforced != null) { + systemNavigationBarContrastEnforced = encodedStyle.systemNavigationBarContrastEnforced as boolean; + } + return new SystemChromeStyle( + statusBarColor, + statusBarIconBrightness, + systemStatusBarContrastEnforced, + systemNavigationBarColor, + systemNavigationBarIconBrightness, + systemNavigationBarDividerColor, + systemNavigationBarContrastEnforced + ); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..564a6df4c4d10c0bdd9dfe22a0b5ec2f3f8e9d5e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/PlatformViewsChannel.ets @@ -0,0 +1,551 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import { ByteBuffer } from '../../../util/ByteBuffer'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG = "PlatformViewsChannel"; +const NON_TEXTURE_FALLBACK = -2; +export default class PlatformViewsChannel { + private channel: MethodChannel; + private handler: PlatformViewsHandler; + private parsingHandler = new ParsingCallback(); + + /** + * Constructs a {@code PlatformViewsChannel} that connects Android to the Dart code running in + * {@code dartExecutor}. + * + *

The given {@code dartExecutor} is permitted to be idle or executing code. + * + *

See {@link DartExecutor}. + */ + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, "flutter/platform_views", StandardMethodCodec.INSTANCE); + this.parsingHandler.platformChannel = this; + this.channel.setMethodCallHandler(this.parsingHandler); + } + + /** + * Sets the {@link PlatformViewsHandler} which receives all events and requests that are parsed + * from the underlying platform views channel. + */ + public setPlatformViewsHandler(handler: PlatformViewsHandler): void { + this.handler = handler; + this.parsingHandler.handler = handler; + } + + public invokeViewFocused(viewId: number): void { + if (this.channel == null) { + return; + } + this.channel.invokeMethod("viewFocused", viewId); + } + + create(call: MethodCall, result: MethodResult): void { + const createArgs: Map = call.args; + const usesPlatformViewLayer: boolean = createArgs.has("hybrid") && createArgs.get("hybrid") as boolean; + const additionalParams: ByteBuffer = createArgs.has("params") ? createArgs.get("params") : null; + + let direction: Direction = Direction.Ltr; + if (createArgs.get("direction") == 0) { + direction = Direction.Ltr; + } else if (createArgs.get("direction") == 1) { + direction = Direction.Rtl; + } + + try { + if (usesPlatformViewLayer) { + const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( + createArgs.get("id"), + createArgs.get("viewType"), + 0, + 0, + 0, + 0, + direction, + additionalParams, + RequestedDisplayMode.HYBRID_ONLY + ); + this.handler.createForPlatformViewLayer(request); + result.success(null); + } else { + const hybridFallback: boolean = createArgs.has("hybridFallback") && createArgs.get("hybridFallback"); + const displayMode: RequestedDisplayMode = + hybridFallback ? RequestedDisplayMode.TEXTURE_WITH_HYBRID_FALLBACK + : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; + const request: PlatformViewCreationRequest = new PlatformViewCreationRequest( + createArgs.get("id"), + createArgs.get("viewType"), + createArgs.has("top") ? createArgs.get("top") : 0.0, + createArgs.has("left") ? createArgs.get("left") : 0.0, + createArgs.get("width"), + createArgs.get("height"), + direction, + additionalParams, + displayMode + ); + + Log.i(TAG, `Create texture param id:${request.viewId}, + type:${request.viewType}, + w:${request.logicalWidth}, + h:${request.logicalHeight}, + l:${request.logicalLeft}, + t:${request.logicalTop}, + d:${request.direction}`); + + const textureId = this.handler.createForTextureLayer(request); + if (textureId == NON_TEXTURE_FALLBACK) { + if (!hybridFallback) { + throw new Error( + "Platform view attempted to fall back to hybrid mode when not requested."); + } + + // A fallback to hybrid mode is indicated with a null texture ID. + result.success(null); + } else { + result.success(textureId); + } + } + } catch (err) { + Log.e(TAG, "create failed" + err); + result.error("error", err, null); + } + } + + dispose(call: MethodCall, result: MethodResult): void { + const disposeArgs: Map = call.args; + const viewId: number = disposeArgs.get("id"); + try { + this.handler.dispose(viewId); + result.success(null); + } catch (err) { + Log.e(TAG, "dispose failed", err); + result.error("error", err, null); + } + } + + resize(call: MethodCall, result: MethodResult): void { + const resizeArgs: Map = call.args; + const resizeRequest: PlatformViewResizeRequest = new PlatformViewResizeRequest( + resizeArgs.get("id"), + resizeArgs.get("width"), + resizeArgs.get("height") + ); + try { + let resizeCallback = new ResizeCallback(); + resizeCallback.result = result; + this.handler.resize(resizeRequest, resizeCallback); + } catch (err) { + Log.e(TAG, "resize failed", err); + result.error("error", err, null); + } + } + + offset(call: MethodCall, result: MethodResult): void { + const offsetArgs: Map = call.args; + try { + this.handler.offset( + offsetArgs.get("id"), + offsetArgs.get("top"), + offsetArgs.get("left")); + result.success(null); + } catch (err) { + Log.e(TAG, "offset failed", err); + result.error("error", err, null); + } + } + + touch(call: MethodCall, result: MethodResult): void { + const args: Array = call.args; + let index = 0; + const touch: PlatformViewTouch = new PlatformViewTouch( + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index++], + args[index] + ); + + try { + this.handler.onTouch(touch); + result.success(null); + } catch (err) { + Log.e(TAG, "offset failed", err); + result.error("error", err, null); + } + } + + setDirection(call: MethodCall, result: MethodResult): void { + const setDirectionArgs: Map = call.args; + const newDirectionViewId: number = setDirectionArgs.get("id"); + const direction: number = setDirectionArgs.get("direction"); + + try { + this.handler.setDirection(newDirectionViewId, direction); + result.success(null); + } catch (err) { + Log.e(TAG, "setDirection failed", err); + result.error("error", err, null); + } + } + + clearFocus(call: MethodCall, result: MethodResult): void { + const viewId: number = call.args; + try { + this.handler.clearFocus(viewId); + result.success(null); + } catch (err) { + Log.e(TAG, "clearFocus failed", err); + result.error("error", err, null); + } + } + + synchronizeToNativeViewHierarchy(call: MethodCall, result: MethodResult): void { + const yes: boolean = call.args; + try { + this.handler.synchronizeToNativeViewHierarchy(yes); + result.success(null); + } catch (err) { + Log.e(TAG, "synchronizeToNativeViewHierarchy failed", err); + result.error("error", err, null); + } + } +} + +/** + * Handler that receives platform view messages sent from Flutter to Ohos through a given + * {@link PlatformViewsChannel}. + * + *

To register a {@code PlatformViewsHandler} with a {@link PlatformViewsChannel}, see {@link + * PlatformViewsChannel#setPlatformViewsHandler(PlatformViewsHandler)}. + */ +export interface PlatformViewsHandler { + /* + * The ID returned by {@code createForTextureLayer} to indicate that the requested texture mode + * was not available and the view creation fell back to {@code PlatformViewLayer} mode. + * + * This can only be returned if the {@link PlatformViewCreationRequest} sets + * {@code TEXTURE_WITH_HYBRID_FALLBACK} as the requested display mode. + */ + + /** + * The Flutter application would like to display a new Ohos {@code View}, i.e., platform + * view. + * + *

The Ohos View is added to the view hierarchy. This view is rendered in the Flutter + * framework by a PlatformViewLayer. + * + * @param request The metadata sent from the framework. + */ + createForPlatformViewLayer(request: PlatformViewCreationRequest): void; + + /** + * The Flutter application would like to display a new Android {@code View}, i.e., platform + * view. + * + *

The Android View is added to the view hierarchy. This view is rendered in the Flutter + * framework by a TextureLayer. + * + * @param request The metadata sent from the framework. + * @return The texture ID. + */ + createForTextureLayer(request: PlatformViewCreationRequest): number; + + /** The Flutter application would like to dispose of an existing Android {@code View}. */ + dispose(viewId: number): void; + + /** + * The Flutter application would like to resize an existing Android {@code View}. + * + * @param request The request to resize the platform view. + * @param onComplete Once the resize is completed, this is the handler to notify the size of the + * platform view buffer. + */ + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void; + + /** + * The Flutter application would like to change the offset of an existing Android {@code View}. + */ + offset(viewId: number, top: number, left: number): void; + + /** + * The user touched a platform view within Flutter. + * + *

Touch data is reported in {@code touch}. + */ + onTouch(touch: PlatformViewTouch): void; + + /** + * The Flutter application would like to change the layout direction of an existing Android + * {@code View}, i.e., platform view. + */ + setDirection(viewId: number, direction: number): void; + + /** Clears the focus from the platform view with a give id if it is currently focused. */ + clearFocus(viewId: number): void; + + /** + * Whether the render surface of {@code FlutterView} should be converted to a {@code + * FlutterImageView} when a {@code PlatformView} is added. + * + *

This is done to syncronize the rendering of the PlatformView and the FlutterView. Defaults + * to true. + */ + synchronizeToNativeViewHierarchy(yes: boolean): void; +} + +/** Platform view display modes that can be requested at creation time. */ +enum RequestedDisplayMode { + /** Use Texture Layer if possible, falling back to Virtual Display if not. */ + TEXTURE_WITH_VIRTUAL_FALLBACK, + /** Use Texture Layer if possible, falling back to Hybrid Composition if not. */ + TEXTURE_WITH_HYBRID_FALLBACK, + /** Use Hybrid Composition in all cases. */ + HYBRID_ONLY, +} + +/** Request sent from Flutter to create a new platform view. */ +export class PlatformViewCreationRequest { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The type of view to create for this platform view. */ + public viewType: string; + + /** The density independent width to display the platform view. */ + public logicalWidth: number; + + /** The density independent height to display the platform view. */ + public logicalHeight: number; + + /** The density independent top position to display the platform view. */ + public logicalTop: number; + + /** The density independent left position to display the platform view. */ + public logicalLeft: number; + + /** + * The layout direction of the new platform view. + */ + public direction: number; + public displayMode: RequestedDisplayMode; + + /** Custom parameters that are unique to the desired platform view. */ + public params: ByteBuffer; + + constructor(viewId: number, viewType: string, logicalTop: number, logicalLeft: number, logicalWidth: number, + logicalHeight: number, direction: Direction, params: ByteBuffer, displayMode?: RequestedDisplayMode) { + this.viewId = viewId; + this.viewType = viewType; + this.logicalTop = logicalTop; + this.logicalLeft = logicalLeft; + this.logicalWidth = logicalWidth; + this.logicalHeight = logicalHeight; + this.direction = direction; + this.displayMode = displayMode ? displayMode : RequestedDisplayMode.TEXTURE_WITH_VIRTUAL_FALLBACK; + this.params = params; + } +} + +/** Request sent from Flutter to resize a platform view. */ +export class PlatformViewResizeRequest { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The new density independent width to display the platform view. */ + public newLogicalWidth: number; + + /** The new density independent height to display the platform view. */ + public newLogicalHeight: number; + + constructor(viewId: number, newLogicalWidth: number, newLogicalHeight: number) { + this.viewId = viewId; + this.newLogicalWidth = newLogicalWidth; + this.newLogicalHeight = newLogicalHeight; + } +} + +/** The platform view buffer size. */ +export class PlatformViewBufferSize { + /** The width of the screen buffer. */ + public width: number; + + /** The height of the screen buffer. */ + public height: number; + + constructor(width: number, height: number) { + this.width = width; + this.height = height; + } +} + +/** Allows to notify when a platform view buffer has been resized. */ +export abstract class PlatformViewBufferResized { + abstract run(bufferSize: PlatformViewBufferSize): void; +} + +/** The state of a touch event in Flutter within a platform view. */ +export class PlatformViewTouch { + /** The ID of the platform view as seen by the Flutter side. */ + public viewId: number; + + /** The amount of time that the touch has been pressed. */ + public downTime: number; + + public eventTime: number; + + public action: number; + + /** The number of pointers (e.g, fingers) involved in the touch event. */ + public pointerCount: number; + + /** Properties for each pointer, encoded in a raw format. */ + public rawPointerPropertiesList: ESObject; + + /** Coordinates for each pointer, encoded in a raw format. */ + public rawPointerCoords: ESObject; + + public metaState: number; + + public buttonState: number; + + /** Coordinate precision along the x-axis. */ + public xPrecision: number; + + /** Coordinate precision along the y-axis. */ + public yPrecision: number; + + public deviceId: number; + + public edgeFlags: number; + + public source: number; + + public flags: number; + + public motionEventId: number; + + constructor(viewId: number, + downTime: number, + eventTime: number, + action: number, + pointerCount: number, + rawPointerPropertiesList: ESObject, + rawPointerCoords: ESObject, + metaState: number, + buttonState: number, + xPrecision: number, + yPrecision: number, + deviceId: number, + edgeFlags: number, + source: number, + flags: number, + motionEventId: number) { + this.viewId = viewId; + this.downTime = downTime; + this.eventTime = eventTime; + this.action = action; + this.pointerCount = pointerCount; + this.rawPointerPropertiesList = rawPointerPropertiesList; + this.rawPointerCoords = rawPointerCoords; + this.metaState = metaState; + this.buttonState = buttonState; + this.xPrecision = xPrecision; + this.yPrecision = yPrecision; + this.deviceId = deviceId; + this.edgeFlags = edgeFlags; + this.source = source; + this.flags = flags; + this.motionEventId = motionEventId; + } +} + +class ParsingCallback implements MethodCallHandler { + platformChannel : PlatformViewsChannel; + handler: PlatformViewsHandler; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.handler == null) { + return; + } + + Log.i(TAG, "Received '" + call.method + "' message."); + switch (call.method) { + case "create": { + this.platformChannel.create(call, result); + break; + } + case "dispose": { + this.platformChannel.dispose(call, result); + break; + } + case "resize": { + this.platformChannel.resize(call, result); + break; + } + case "offset": { + this.platformChannel.offset(call, result); + break; + } + case "touch": { + this.platformChannel.touch(call, result); + break; + } + case "setDirection": { + this.platformChannel.setDirection(call, result); + break; + } + case "clearFocus": { + this.platformChannel.clearFocus(call, result); + break; + } + case "synchronizeToNativeViewHierarchy": { + this.platformChannel.synchronizeToNativeViewHierarchy(call, result); + break; + } + default: + result.notImplemented(); + } + } +} + +class ResizeCallback extends PlatformViewBufferResized { + result : MethodResult; + run(bufferSize: PlatformViewBufferSize) { + if (bufferSize == null) { + this.result.error("error", "Failed to resize the platform view", null); + } else { + const response: Map = new Map(); + response.set("width", bufferSize.width); + response.set("height", bufferSize.height); + this.result.success(response); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..bcf53050d567f4fc61237845d4019c669873540c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/RestorationChannel.ets @@ -0,0 +1,175 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import StandardMethodCodec from '../../../plugin/common/StandardMethodCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +/** + * System channel to exchange restoration data between framework and engine. + * + *

The engine can obtain the current restoration data from the framework via this channel to + * store it on disk and - when the app is relaunched - provide the stored data back to the framework + * to recreate the original state of the app. + * + *

The channel can be configured to delay responding to the framework's request for restoration + * data via {@code waitForRestorationData} until the engine-side has provided the data. This is + * useful when the engine is pre-warmed at a point in the application's life cycle where the + * restoration data is not available yet. For example, if the engine is pre-warmed as part of the + * Application before an Activity is created, this flag should be set to true because Android will + * only provide the restoration data to the Activity during the onCreate callback. + * + *

The current restoration data provided by the framework can be read via {@code + * getRestorationData()}. + */ +export default class RestorationChannel { + private static TAG = "RestorationChannel"; + private static CHANNEL_NAME = "flutter/restoration"; + + /** + * Whether the channel delays responding to the framework's initial request for restoration data + * until {@code setRestorationData} has been called. + * + *

If the engine never calls {@code setRestorationData} this flag must be set to false. If set + * to true, the engine must call {@code setRestorationData} either with the actual restoration + * data as argument or null if it turns out that there is no restoration data. + * + *

If the response to the framework's request for restoration data is not delayed until the + * data has been set via {@code setRestorationData}, the framework may intermittently initialize + * itself to default values until the restoration data has been made available. Setting this flag + * to true avoids that extra work. + */ + public waitForRestorationData: boolean; + + // Holds the most current restoration data which may have been provided by the engine + // via "setRestorationData" or by the framework via the method channel. This is the data the + // framework should be restored to in case the app is terminated. + private restorationData: Uint8Array = new Uint8Array(); + private channel: MethodChannel; + private pendingFrameworkRestorationChannelRequest: MethodResult; + private engineHasProvidedData: boolean = false; + private frameworkHasRequestedData: boolean = false; + private handler: MethodCallHandler = new RestorationChannelMethodCallHandler(this.restorationData); + + constructor(channelOrExecutor: MethodChannel | DartExecutor, waitForRestorationData: boolean) { + if (channelOrExecutor instanceof MethodChannel) { + this.channel = channelOrExecutor; + } else { + this.channel = new MethodChannel(channelOrExecutor, RestorationChannel.CHANNEL_NAME, StandardMethodCodec.INSTANCE); + } + this.waitForRestorationData = waitForRestorationData; + this.channel.setMethodCallHandler(this.handler); + } + + /** Obtain the most current restoration data that the framework has provided. */ + getRestorationData(): Uint8Array { + return this.restorationData; + } + + /** Set the restoration data from which the framework will restore its state. */ + setRestorationData(data: Uint8Array) { + this.engineHasProvidedData = true; + if (this.pendingFrameworkRestorationChannelRequest != null) { + // If their is a pending request from the framework, answer it. + this.pendingFrameworkRestorationChannelRequest.success(RestorationChannelMethodCallHandler.packageData(data)); + this.pendingFrameworkRestorationChannelRequest = null; + this.restorationData = data; + } else if (this.frameworkHasRequestedData) { + // If the framework has previously received the engine's restoration data, push the new data + // directly to it. This case can happen when "waitForRestorationData" is false and the + // framework retrieved the restoration state before it was set via this method. + // Experimentally, this can also be used to restore a previously used engine to another state, + // e.g. when the engine is attached to a new activity. + this.channel.invokeMethod("push", RestorationChannelMethodCallHandler.packageData(data), { + success: (result: ESObject) :void => { + this.restorationData = data; + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) :void => { + Log.e(RestorationChannel.TAG, + "Error " + errorCode + " while sending restoration data to framework: " + errorMessage); + }, + + notImplemented: () :void => { + // do nothing + } + }) + } else { + // Otherwise, just cache the data until the framework asks for it. + this.restorationData = data; + } + } + + /** + * Clears the current restoration data. + * + *

This should be called just prior to a hot restart. Otherwise, after the hot restart the + * state prior to the hot restart will get restored. + */ + clearData() { + this.restorationData = null; + } +} + +class RestorationChannelMethodCallHandler implements MethodCallHandler { + public waitForRestorationData: boolean; + private restorationData: Uint8Array; + private engineHasProvidedData: boolean = false; + private frameworkHasRequestedData: boolean = false; + private channel: MethodChannel; + private pendingFrameworkRestorationChannelRequest: MethodResult; + + constructor(restorationData: Uint8Array) { + this.restorationData = restorationData; + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + const method = call.method; + const args: ESObject = call.args; + switch (method) { + case "put": { + this.restorationData = args; + result.success(null); + break; + } + case "get": { + this.frameworkHasRequestedData = true; + if (this.engineHasProvidedData || !this.waitForRestorationData) { + result.success(RestorationChannelMethodCallHandler.packageData(this.restorationData)); + // Do not delete the restoration data on the engine side after sending it to the + // framework. We may need to hand this data back to the operating system if the + // framework never modifies the data (and thus doesn't send us any + // data back). + } else { + this.pendingFrameworkRestorationChannelRequest = result; + } + break; + } + default: { + result.notImplemented(); + break; + } + } + } + + static packageData(data: Uint8Array): Map { + const packaged: Map = new Map(); + packaged.set("enabled", true); + packaged.set("data", data); + return packaged; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..b40cd5536a335c48b0d9c9defabc02cfdea50f7e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SettingsChannel.ets @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +export enum PlatformBrightness { + LIGHT = "light", + DARK = "dark" +} + +const TAG = "SettingsChannel"; +const TEXT_SCALE_FACTOR = "textScaleFactor"; +const NATIVE_SPELL_CHECK_SERVICE_DEFINED = "nativeSpellCheckServiceDefined"; +const BRIEFLY_SHOW_PASSWORD = "brieflyShowPassword"; +const ALWAYS_USE_24_HOUR_FORMAT = "alwaysUse24HourFormat"; +const PLATFORM_BRIGHTNESS = "platformBrightness"; +export default class SettingsChannel { + private static CHANNEL_NAME = "flutter/settings"; + + private channel: BasicMessageChannel; + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, SettingsChannel.CHANNEL_NAME, JSONMessageCodec.INSTANCE); + } + + startMessage(): MessageBuilder { + return new MessageBuilder(this.channel); + } +} + +class MessageBuilder { + private channel: BasicMessageChannel; + private message: Map = new Map(); + + constructor(channel: BasicMessageChannel) { + this.channel = channel; + } + + setTextScaleFactor(textScaleFactor: Number): MessageBuilder { + this.message.set(TEXT_SCALE_FACTOR, textScaleFactor); + return this; + } + + setNativeSpellCheckServiceDefined(nativeSpellCheckServiceDefined: boolean): MessageBuilder { + this.message.set(NATIVE_SPELL_CHECK_SERVICE_DEFINED, nativeSpellCheckServiceDefined); + return this; + } + + setBrieflyShowPassword(brieflyShowPassword: boolean): MessageBuilder { + this.message.set(BRIEFLY_SHOW_PASSWORD, brieflyShowPassword); + return this; + } + + setAlwaysUse24HourFormat(alwaysUse24HourFormat: boolean): MessageBuilder { + this.message.set(ALWAYS_USE_24_HOUR_FORMAT, alwaysUse24HourFormat); + return this; + } + + setPlatformBrightness(platformBrightness: PlatformBrightness): MessageBuilder { + this.message.set(PLATFORM_BRIGHTNESS, platformBrightness); + return this; + } + + send(): void { + Log.i(TAG, "Sending message: \n" + + "textScaleFactor: " + + this.message.get(TEXT_SCALE_FACTOR) + + "alwaysUse24HourFormat: " + + this.message.get(ALWAYS_USE_24_HOUR_FORMAT) + + "platformBrightness: " + + this.message.get(PLATFORM_BRIGHTNESS)) + this.channel.send(this.message) + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..9f9ef28154563799368fbbe816ceed3cd78f0d3e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/SystemChannel.ets @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; +const TAG: string = "SystemChannel"; + +/** + * fill in javadoc for SystemChannel. + */ +export default class SystemChannel { + public channel: BasicMessageChannel; + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, "flutter/system", JSONMessageCodec.INSTANCE); + } + + public sendMemoryPressureWarning(): void { + Log.i(TAG, "Sending memory pressure warning to Flutter"); + let message : Map = new Map().set("type", "memoryPressure"); + this.channel.send(message); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..d54c448e027d069baaacbe66bf877c50823cb6d5 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TestChannel.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel, { MessageHandler, Reply } from '../../../plugin/common/BasicMessageChannel'; +import JSONMessageCodec from '../../../plugin/common/JSONMessageCodec'; +import DartExecutor from '../dart/DartExecutor'; +import Log from '../../../util/Log'; + +const TAG = "TestChannel" + +export default class TestChannel { + private channel: BasicMessageChannel + + constructor(dartExecutor: DartExecutor) { + this.channel = new BasicMessageChannel(dartExecutor, "flutter/test", JSONMessageCodec.INSTANCE); + let callback = new MessageCallback(); + this.channel.setMessageHandler(callback); + } +} + +class MessageCallback implements MessageHandler { + onMessage(message: string, reply: Reply) { + Log.d(TAG, "receive msg = " + message); + reply.reply("收到消息啦:" + message); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..afdbecc9829a7520eef0c3409545572be381a96b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/engine/systemchannels/TextInputChannel.ets @@ -0,0 +1,365 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import JSONMethodCodec from '../../../plugin/common/JSONMethodCodec'; +import MethodCall from '../../../plugin/common/MethodCall'; +import MethodChannel, { MethodCallHandler, MethodResult } from '../../../plugin/common/MethodChannel'; +import TextInputPlugin from '../../../plugin/editing/TextInputPlugin'; +import Log from '../../../util/Log'; +import DartExecutor from '../dart/DartExecutor'; + +const TAG = "TextInputChannel"; + +export default class TextInputChannel { + private static CHANNEL_NAME = "flutter/textinput"; + public channel: MethodChannel; + textInputMethodHandler: TextInputMethodHandler; + + constructor(dartExecutor: DartExecutor) { + this.channel = new MethodChannel(dartExecutor, TextInputChannel.CHANNEL_NAME, JSONMethodCodec.INSTANCE); + let callback = new TextInputCallback(); + callback.textInputMethodHandler = this.textInputMethodHandler; + this.channel.setMethodCallHandler(callback); + } + + setTextInputMethodHandler(textInputMethodHandler: TextInputMethodHandler): void { + this.textInputMethodHandler = textInputMethodHandler; + } + + requestExistingInputState(): void { + this.channel.invokeMethod("TextInputClient.requestExistingInputState", null); + } + + createEditingStateJSON(text: String, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number): ESObject { + return new Map() + .set("text", text) + .set("selectionBase", selectionStart) + .set("selectionExtent", selectionEnd) + .set("composingBase", composingStart) + .set("composingExtent", composingEnd); + } + + /** + * Instructs Flutter to update its text input editing state to reflect the given configuration. + */ + updateEditingState(inputClientId: number, + text: String, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number): void { + Log.d(TAG, "updateEditingState:" + + "Text: " + text + " Selection start: " + selectionStart + " Selection end: " + + selectionEnd + " Composing start: " + composingStart + " Composing end: " + composingEnd); + const state: ESObject = this.createEditingStateJSON(text, selectionStart, selectionEnd, composingStart, composingEnd); + this.channel.invokeMethod('TextInputClient.updateEditingState', [inputClientId, state]); + Log.d(TAG,"updateEditingState end"); + + } + + newline(inputClientId: number): void { + Log.d(TAG, "Sending 'newline' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.newline"]); + } + + go(inputClientId: number): void { + Log.d(TAG, "Sending 'go' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.go"]); + } + + search(inputClientId: number): void { + Log.d(TAG, "Sending 'search' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.search"]); + } + + send(inputClientId: number): void { + Log.d(TAG, "Sending 'send' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.send"]); + } + + done(inputClientId: number): void { + Log.d(TAG, "Sending 'done' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.done"]); + } + + next(inputClientId: number): void { + Log.d(TAG, "Sending 'next' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.next"]); + } + + previous(inputClientId: number): void { + Log.d(TAG, "Sending 'previous' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.previous"]); + } + + unspecifiedAction(inputClientId: number): void { + Log.d(TAG, "Sending 'unspecifiedAction' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.unspecifiedAction"]); + } + + commitContent(inputClientId: number): void { + Log.d(TAG, "Sending 'commitContent' message."); + this.channel.invokeMethod("TextInputClient.performAction", [inputClientId, "TextInputAction.commitContent"]); + } + + performPrivateCommand(inputClientId: number, action: string, data: ESObject) { + + } + + + +} + + +export interface TextInputMethodHandler { + show(): void; + + hide(): void; + + requestAutofill(): void; + + finishAutofillContext(shouldSave: boolean): void; + + setClient(textInputClientId: number, configuration: Configuration): void; + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void; + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void; + + setEditingState(editingState: TextEditState): void; + + clearClient(): void; + +} + +export class Configuration { + obscureText: boolean; + autocorrect: boolean; + enableSuggestions: boolean; + enableIMEPersonalizedLearning: boolean; + enableDeltaModel: boolean; + textCapitalization: TextCapitalization; + inputType:InputType; + inputAction: Number; + actionLabel: String; + contentCommitMimeTypes: String[]; + fields: Configuration[]; + + constructor(obscureText: boolean, + autocorrect: boolean, + enableSuggestions: boolean, + enableIMEPersonalizedLearning: boolean, + enableDeltaModel: boolean, + inputType: InputType, + inputAction: Number, + actionLabel: String, ) { + } + getTextCapitalizationFromValue(encodedName: string): TextCapitalization { + let textKeys = [ + TextCapitalization.CHARACTERS, TextCapitalization.WORDS, + TextCapitalization.SENTENCES, TextCapitalization.NONE + ]; + for (let i = 0; i < textKeys.length; i++) { + let key = textKeys[i]; + if (TextCapitalization[key] === encodedName) { + return key; + } + } + throw new Error("No such TextCapitalization: " + encodedName); + } +} + +enum TextCapitalization { + CHARACTERS = "TextCapitalization.characters", + WORDS = "TextCapitalization.words", + SENTENCES = "TextCapitalization.sentences", + NONE = "TextCapitalization.none", +} + +export enum TextInputType { + TEXT = "TextInputType.text", + DATETIME = "TextInputType.datetime", + NAME = "TextInputType.name", + POSTAL_ADDRESS = "TextInputType.address", + NUMBER = "TextInputType.number", + PHONE = "TextInputType.phone", + MULTILINE = "TextInputType.multiline", + EMAIL_ADDRESS = "TextInputType.emailAddress", + URL = "TextInputType.url", + VISIBLE_PASSWORD = "TextInputType.visiblePassword", + NONE = "TextInputType.none", +} + +export class InputType { + type: TextInputType; + isSigned: boolean; + isDecimal: boolean; + + constructor(type: TextInputType, isSigned: boolean, isDecimal: boolean) { + this.type = type; + this.isSigned = isSigned; + this.isDecimal = isDecimal; + } + + static fromJson(json: ESObject): InputType { + return new InputType(InputType.getTextInputTypeFromValue(json.name as string), + json.signed as boolean, json.decimal as boolean) + } + + static getTextInputTypeFromValue(encodedName: string): TextInputType { + let textKeys = [ + TextInputType.TEXT, TextInputType.DATETIME, TextInputType.NAME, + TextInputType.POSTAL_ADDRESS, TextInputType.NUMBER, TextInputType.PHONE, + TextInputType.MULTILINE, TextInputType.EMAIL_ADDRESS, TextInputType.URL, + TextInputType.VISIBLE_PASSWORD, TextInputType.NONE + ]; + for (let i = 0; i < textKeys.length; i++) { + let key = textKeys[i]; + if (TextInputType[key] == encodedName) { + return key; + } + } + throw new Error("No such TextInputType: " + encodedName); + } +} + +export class TextEditState { + private static TAG = "TextEditState"; + text: string; + selectionStart: number; + selectionEnd: number; + composingStart: number; + composingEnd: number; + + constructor(text: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number) { + if ((selectionStart != -1 || selectionEnd != -1) + && (selectionStart < 0 || selectionEnd < 0)) { + throw new Error("invalid selection: (" + selectionStart + ", " + selectionEnd + ")"); + } + + if ((composingStart != -1 || composingEnd != -1) + && (composingStart < 0 || composingStart > composingEnd)) { + throw new Error("invalid composing range: (" + composingStart + ", " + composingEnd + ")"); + } + + if (composingEnd > text.length) { + throw new Error("invalid composing start: " + composingStart); + } + + if (selectionStart > text.length) { + throw new Error("invalid selection start: " + selectionStart); + } + + if (selectionEnd > text.length) { + throw new Error("invalid selection end: " + selectionEnd); + } + + this.text = text; + this.selectionStart = selectionStart; + this.selectionEnd = selectionEnd; + this.composingStart = composingStart; + this.composingEnd = composingEnd; + } + + hasSelection(): boolean { + // When selectionStart == -1, it's guaranteed that selectionEnd will also + // be -1. + return this.selectionStart >= 0; + } + + hasComposing(): boolean { + return this.composingStart >= 0 && this.composingEnd > this.composingStart; + } + + static fromJson(textEditState: ESObject): TextEditState { + return new TextEditState( + textEditState.text, + textEditState.selectionBase, + textEditState.selectionExtent, + textEditState.composingBase, + textEditState.composingExtent + ) + } +} + +class TextInputCallback implements MethodCallHandler { + textInputMethodHandler: TextInputMethodHandler; + + onMethodCall(call: MethodCall, result: MethodResult) { + if (this.textInputMethodHandler == null) { + return; + } + let method: string = call.method; + let args: ESObject = call.args; + Log.d(TAG, "Received '" + method + "' message."); + switch (method) { + case "TextInput.show": + this.textInputMethodHandler.show(); + Log.d(TAG, "textInputMethodHandler.show()"); + result.success(null); + break; + case "TextInput.hide": + this.textInputMethodHandler.hide(); + result.success(null); + break; + case "TextInput.setClient": + const textInputClientId: number = args[0] as number; + //TODO: parse configuration + const config: Configuration = null; + this.textInputMethodHandler.setClient(textInputClientId, config); + result.success(null); + break; + case "TextInput.requestAutofill": + //TODO: requestAutofill + result.notImplemented(); + break; + case "TextInput.setPlatformViewClient": + //TODO: + result.notImplemented(); + break; + case "TextInput.setEditingState": + this.textInputMethodHandler.setEditingState(TextEditState.fromJson(args)); + result.success(null); + break; + case "TextInput.setEditableSizeAndTransform": + //TODO: + result.notImplemented(); + break; + case "TextInput.clearClient": + this.textInputMethodHandler.clearClient(); + result.success(null); + break; + case "TextInput.sendAppPrivateCommand": + //TODO: + result.notImplemented(); + break; + case "TextInput.finishAutofillContext": + //TODO: + result.notImplemented(); + break; + default: + result.notImplemented(); + break; + } + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets new file mode 100644 index 0000000000000000000000000000000000000000..f7ecfc7d5ef46c57923679789eb82f86eb83ef77 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/ExclusiveAppComponent.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default interface ExclusiveAppComponent { + /** + * Called when another App Component is about to become attached to the {@link + * io.flutter.embedding.engine.FlutterEngine} this App Component is currently attached to. + * + *

This App Component's connections to the {@link io.flutter.embedding.engine.FlutterEngine} + * are still valid at the moment of this call. + */ + detachFromFlutterEngine(): void; + + /** + * Retrieve the App Component behind this exclusive App Component. + * + * @return The app component. + */ + getAppComponent(): T; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..07a374a7109e9a1ffcd5680220534c9796681e64 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbility.ets @@ -0,0 +1,414 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import window from '@ohos.window'; +import { FlutterAbilityDelegate, Host } from './FlutterAbilityDelegate'; +import Log from '../../util/Log'; +import FlutterEngine from '../engine/FlutterEngine'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import common from '@ohos.app.ability.common'; +import Want from '@ohos.app.ability.Want'; +import display from '@ohos.display'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import { AsyncCallback } from '@ohos.base'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import I18n from '@ohos.i18n' +import { PlatformBrightness } from '../engine/systemchannels/SettingsChannel'; +import ConfigurationConstant from '@ohos.app.ability.ConfigurationConstant'; +import { DVModelContainer } from '../../view/DynamicView/dynamicView'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { Configuration } from '@ohos.app.ability.Configuration'; + +const TAG = "FlutterAbility"; +/** + * flutter ohos基础ability,请在让主ability继承自该类。 + * 该类主要职责: + * 1、持有FlutterAbilityDelegate并初始化; + * 2、生命周期传递; + */ +export class FlutterAbility extends UIAbility implements Host { + private delegate: FlutterAbilityDelegate; + private windowStage: window.WindowStage; + private mainWindow: window.Window; + private viewportMetrics = new ViewportMetrics(); + private displayInfo: display.Display; + + /** + * onCreate + * 1、create and attach delegate + * 2、config windows transparent noNeed? + * 3、lifecycle.onCreate + * 4. setContentView() noNeed + */ + async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam) { + Log.i(TAG, "bundleCodeDir=" + this.context.bundleCodeDir); + // globalThis.flutterAbility = this + this.displayInfo = display.getDefaultDisplaySync(); + this.viewportMetrics.devicePixelRatio = this.displayInfo.densityPixels + + this.delegate = new FlutterAbilityDelegate(this); + await this.delegate.onAttach(this.context); + Log.i(TAG, 'onAttach end'); + this.delegate.platformPlugin.setUIAbilityContext(this.context); + this.delegate.onRestoreInstanceState(want); + this.delegate.sendSettings(); + + if (this.stillAttachedForEvent("onCreate")) { + this.delegate.onCreate(); + } + + console.log('MyAbility onCreate'); + // globalThis.applicationContext = this.context.getApplicationContext(); + } + + onDestroy() { + if (this.stillAttachedForEvent("onDestroy")) { + this.delegate.onDestroy(); + } + } + + /** + * window状态改变回调 + * @param windowStage + */ + async onWindowStageCreate(windowStage: window.WindowStage) { + this.windowStage = windowStage + try { + windowStage.on('windowStageEvent', (data) => { + let stageEventType: window.WindowStageEventType = data; + switch (stageEventType) { + case window.WindowStageEventType.SHOWN: // 切到前台 + Log.i(TAG, 'windowStage foreground.'); + break; + case window.WindowStageEventType.ACTIVE: // 获焦状态 + Log.i(TAG, 'windowStage active.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(true); + } + break; + case window.WindowStageEventType.INACTIVE: // 失焦状态 + Log.i(TAG, 'windowStage inactive.'); + if (this.stillAttachedForEvent("onWindowFocusChanged")) { + this.delegate.onWindowFocusChanged(false); + } + break; + case window.WindowStageEventType.HIDDEN: // 切到后台 + Log.i(TAG, 'windowStage background.'); + break; + default: + break; + } + }); + + this.mainWindow = windowStage.getMainWindowSync() + this.mainWindow.on('windowSizeChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('avoidAreaChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.mainWindow.on('keyboardHeightChange', (data) => { + this.onWindowPropertiesUpdated(); + }); + + this.loadContent(); + this.mainWindow.setWindowLayoutFullScreen(true); + } catch (exception) { + Log.e(TAG, 'Failed to enable the listener for window stage event changes. Cause:' + JSON.stringify(exception)); + } + } + + loadContent() { + if (this.windowStage != null && this.stillAttachedForEvent("loadContent")) { + Log.i(TAG, 'loadContent'); + this.windowStage.loadContent('pages/Index', (err, data) => { + if (err.code) { + Log.e(TAG, 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + this.onWindowPropertiesUpdated(); + Log.i(TAG, 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? ''); + }); + if (this.stillAttachedForEvent("onWindowStageCreate")) { + this.delegate.onWindowStageCreate(); + } + this.delegate.getFlutterNapi().updateRefreshRate(this.displayInfo.refreshRate) + this.onFlutterEngineReady() + } + } + + onFlutterEngineReady(): void { + + } + + private updateViewportMetrics() { + this.delegate.getFlutterNapi().setViewportMetrics(this.viewportMetrics.devicePixelRatio, + this.viewportMetrics.physicalWidth, + this.viewportMetrics.physicalHeight, + this.viewportMetrics.physicalViewPaddingTop, + this.viewportMetrics.physicalViewPaddingRight, + this.viewportMetrics.physicalViewPaddingBottom, + this.viewportMetrics.physicalViewPaddingLeft, + this.viewportMetrics.physicalViewInsetTop, + this.viewportMetrics.physicalViewInsetRight, + this.viewportMetrics.physicalViewInsetBottom, + this.viewportMetrics.physicalViewInsetLeft, + this.viewportMetrics.systemGestureInsetTop, + this.viewportMetrics.systemGestureInsetRight, + this.viewportMetrics.systemGestureInsetBottom, + this.viewportMetrics.systemGestureInsetLeft, + this.viewportMetrics.physicalTouchSlop, + new Array(0), + new Array(0), + new Array(0)) + } + + onWindowStageDestroy() { + if (this.stillAttachedForEvent("onWindowStageDestroy")) { + this.delegate.onWindowStageDestroy(); + } + } + + onForeground() { + if (this.stillAttachedForEvent("onForeground")) { + this.delegate.onForeground(); + } + } + + onBackground() { + if (this.stillAttachedForEvent("onBackground")) { + this.delegate.onBackground(); + } + } + + release() { + if (this.delegate != null) { + this.delegate.release(); + this.delegate = null; + } + } + + /** + * host所有实现方法开始======start + */ + + getAbility(): UIAbility { + return this; + } + + shouldDispatchAppLifecycleState(): boolean { + return true; + } + + provideFlutterEngine(context: common.Context): FlutterEngine { + return null; + } + + configureFlutterEngine(flutterEngine: FlutterEngine) { + + } + + cleanUpFlutterEngine(flutterEngine: FlutterEngine) { + + } + + getFlutterShellArgs(): FlutterShellArgs { + return FlutterShellArgs.fromWant(this.getWant()); + } + + getDartEntrypointArgs(): Array { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT_ARGS] as Array; + } + return new Array() + } + + detachFromFlutterEngine() { + if (this.delegate != null) { + this.delegate.onDetach(); + } + } + + popSystemNavigator(): boolean { + return false; + } + + shouldAttachEngineToActivity(): boolean { + return true; + } + + getDartEntrypointLibraryUri(): string { + return null; + } + + getAppBundlePath(): string { + return null; + } + + getDartEntrypointFunctionName(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_DART_ENTRYPOINT] as string; + } + return FlutterAbilityLaunchConfigs.DEFAULT_DART_ENTRYPOINT + } + + getInitialRoute(): string { + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE]) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_INITIAL_ROUTE] as string; + } + return null + } + + getWant(): Want { + return this.launchWant; + } + + shouldDestroyEngineWithHost(): boolean { + return true; + } + + shouldRestoreAndSaveState(): boolean{ + if (this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] != undefined) { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as boolean; + } + if (this.getCachedEngineId() != null) { + // Prevent overwriting the existing state in a cached engine with restoration state. + return false; + } + return true; + } + + getCachedEngineId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_ID] as string + } + + getCachedEngineGroupId(): string { + return this.launchWant.parameters[FlutterAbilityLaunchConfigs.EXTRA_CACHED_ENGINE_GROUP_ID] as string + } + + /** + * host所有实现方法结束======end + */ + private stillAttachedForEvent(event: string) { + Log.i(TAG, 'Ability ' + event); + if (this.delegate == null) { + Log.w(TAG, "FlutterAbility " + event + " call after release."); + return false; + } + if (!this.delegate.isAttached) { + Log.w(TAG, "FlutterAbility " + event + " call after detach."); + return false; + } + return true; + } + + addPlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.addPlugin(plugin) + } + } + + removePlugin(plugin: FlutterPlugin): void { + if (this.delegate != null) { + this.delegate.removePlugin(plugin) + } + } + + private onWindowPropertiesUpdated(){ + if (!this.delegate.isAttached) { + return; + } + let systemAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM); + let gestureAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM_GESTURE); + let keyboardAvoidArea = this.mainWindow.getWindowAvoidArea(window.AvoidAreaType.TYPE_KEYBOARD); + const properties = this.mainWindow.getWindowProperties(); + this.viewportMetrics.physicalWidth = properties.windowRect.width; + this.viewportMetrics.physicalHeight = properties.windowRect.height; + + this.viewportMetrics.physicalViewPaddingTop = systemAvoidArea.topRect.height + this.viewportMetrics.physicalViewPaddingLeft = systemAvoidArea.leftRect.width + this.viewportMetrics.physicalViewPaddingBottom = systemAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewPaddingRight = systemAvoidArea.rightRect.width + + this.viewportMetrics.physicalViewInsetTop = keyboardAvoidArea.topRect.height + this.viewportMetrics.physicalViewInsetLeft = keyboardAvoidArea.leftRect.width + this.viewportMetrics.physicalViewInsetBottom = keyboardAvoidArea.bottomRect.height + this.viewportMetrics.physicalViewInsetRight = keyboardAvoidArea.rightRect.width + + this.viewportMetrics.systemGestureInsetTop = gestureAvoidArea.topRect.height + this.viewportMetrics.systemGestureInsetLeft = gestureAvoidArea.leftRect.width + this.viewportMetrics.systemGestureInsetBottom = gestureAvoidArea.bottomRect.height + this.viewportMetrics.systemGestureInsetRight = gestureAvoidArea.rightRect.width + + this.updateViewportMetrics() + } + + onMemoryLevel(level: AbilityConstant.MemoryLevel): void { + Log.i(TAG, 'onMemoryLevel: ' + level); + if (level === AbilityConstant.MemoryLevel.MEMORY_LEVEL_CRITICAL) { + this.delegate.onLowMemory(); + } + } + + onConfigurationUpdated(config: Configuration){ + Log.i(TAG, 'onConfigurationUpdated config:' + JSON.stringify(config)); + this.delegate.flutterEngine.getSettingsChannel().startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setPlatformBrightness(config.colorMode != ConfigurationConstant.ColorMode.COLOR_MODE_DARK + ? PlatformBrightness.LIGHT : PlatformBrightness.DARK); + } + + getWindowId(callback: AsyncCallback): void { + if (callback === null) { + return; + } + try { + window.getLastWindow(this.context, (error, win) => { + if (error.code) { + callback(error, -1); + return; + } + let windowId = win.getWindowProperties().id; + callback(error, windowId); + }); + } catch (err) { + Log.e(TAG, "get window id error!"); + callback(err, -1); + } + } +} + +export class ViewportMetrics { + devicePixelRatio: number = 1.0; + physicalWidth: number = 0; + physicalHeight: number = 0; + physicalViewPaddingTop: number = 0; + physicalViewPaddingRight: number = 0; + physicalViewPaddingBottom: number = 0; + physicalViewPaddingLeft: number = 0; + physicalViewInsetTop: number = 0; + physicalViewInsetRight: number = 0; + physicalViewInsetBottom: number = 0; + physicalViewInsetLeft: number = 0; + systemGestureInsetTop: number = 0; + systemGestureInsetRight: number = 0; + systemGestureInsetBottom: number = 0; + systemGestureInsetLeft: number = 0; + physicalTouchSlop = -1; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..9046981a47219a7eb553dd4d3baeefa639069281 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityDelegate.ets @@ -0,0 +1,440 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import FlutterEngineConfigurator from './FlutterEngineConfigurator'; +import FlutterEngineProvider from './FlutterEngineProvider'; +import FlutterEngine from '../engine/FlutterEngine'; +import PlatformPlugin, { PlatformPluginDelegate } from '../../plugin/PlatformPlugin'; +import Want from '@ohos.app.ability.Want'; +import FlutterShellArgs from '../engine/FlutterShellArgs'; +import DartExecutor, { DartEntrypoint } from '../engine/dart/DartExecutor'; +import FlutterAbilityLaunchConfigs from './FlutterAbilityLaunchConfigs'; +import Log from '../../util/Log'; +import FlutterInjector from '../../FlutterInjector'; +import UIAbility from '@ohos.app.ability.UIAbility'; +import ExclusiveAppComponent from './ExclusiveAppComponent'; +import AbilityConstant from '@ohos.app.ability.AbilityConstant'; +import TextInputPlugin from '../../plugin/editing/TextInputPlugin'; +import { FlutterPlugin } from '../engine/plugins/FlutterPlugin'; +import FlutterEngineCache from '../engine/FlutterEngineCache'; +import FlutterEngineGroupCache from '../engine/FlutterEngineGroupCache'; +import FlutterEngineGroup, { Options } from '../engine/FlutterEngineGroup'; +import MouseCursorPlugin, { MouseCursorViewDelegate } from '../../plugin/mouse/MouseCursorPlugin'; +import Settings from './Settings'; + +const TAG = "FlutterAbilityDelegate"; +const PLUGINS_RESTORATION_BUNDLE_KEY = "plugins"; +const FRAMEWORK_RESTORATION_BUNDLE_KEY = "framework"; + +/** + * 主要职责: + * 1、初始化engine + * 2、处理ability生命周期回调 + */ +class FlutterAbilityDelegate implements ExclusiveAppComponent { + private host: Host; + flutterEngine: FlutterEngine; + platformPlugin: PlatformPlugin; + private context: common.Context; + private textInputPlugin: TextInputPlugin; + private isFlutterEngineFromHost: boolean; + private engineGroup: FlutterEngineGroup; + private mouseCursorPlugin: MouseCursorPlugin; + private settings: Settings; + + constructor(host: Host) { + this.host = host; + } + + /** + * 是否还attach在ability上 + */ + isAttached = false; + + async onAttach(context: common.Context): Promise { + this.context = context; + this.ensureAlive(); + if (this.flutterEngine == null) { + await this.setupFlutterEngine(); + } + //shouldAttachEngineToActivity + if (this.host.shouldAttachEngineToActivity()) { + // Notify any plugins that are currently attached to our FlutterEngine that they + // are now attached to an Ability. + Log.d(TAG, "Attaching FlutterEngine to the Ability that owns this delegate."); + this.flutterEngine.getAbilityControlSurface().attachToAbility(this); + } + + //providePlatformPlugin + + //configureFlutterEngine + this.isAttached = true; + Log.d(TAG, "onAttach end start loadcontent") + this.host.loadContent() + this.textInputPlugin = new TextInputPlugin(this.flutterEngine.getTextInputChannel()); + this.platformPlugin = new PlatformPlugin(this.flutterEngine.getPlatformChannel(), this.context); + this.mouseCursorPlugin = new MouseCursorPlugin(this.host, this.flutterEngine.getMouseCursorChannel()); + this.settings = new Settings(this.flutterEngine.getSettingsChannel()); + this.flutterEngine.getSystemLanguages(); + } + + /** + * 加载app.so资源或者snapshot + */ + private doInitialFlutterViewRun(): void { + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + const libraryUri = this.host.getDartEntrypointLibraryUri(); + Log.d(TAG, "Executing Dart entrypoint: " + this.host.getDartEntrypointFunctionName() + ", library uri: " + libraryUri == null ? "\"\"" : libraryUri + ", and sending initial route: " + initialRoute); + + // The engine needs to receive the Flutter app's initial route before executing any + // Dart code to ensure that the initial route arrives in time to be applied. + this.flutterEngine.getNavigationChannel().setInitialRoute(initialRoute); + + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride == '') { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint: DartEntrypoint = new DartEntrypoint( + appBundlePathOverride, + this.host.getDartEntrypointLibraryUri(), + this.host.getDartEntrypointFunctionName() + ); + this.flutterEngine.dartExecutor.executeDartEntrypoint(dartEntrypoint, this.host.getDartEntrypointArgs()); + } + + private maybeGetInitialRouteFromIntent(want: Want): string { + return null; + } + + + /** + * 通过参数,配置flutterEngine + * @param want + */ + onRestoreInstanceState(want: Want) { + let frameworkState: Uint8Array = want.parameters[FRAMEWORK_RESTORATION_BUNDLE_KEY] as Uint8Array; + if (this.host.shouldRestoreAndSaveState()) { + this.flutterEngine.getRestorationChannel().setRestorationData(frameworkState ?? null); + } + } + + /** + * 初始化flutterEngine + */ + async setupFlutterEngine() { + // First, check if the host wants to use a cached FlutterEngine. + const cachedEngineId = this.host.getCachedEngineId(); + Log.d(TAG, "cachedEngineId=" + cachedEngineId); + if (cachedEngineId && cachedEngineId.length > 0) { + this.flutterEngine = FlutterEngineCache.getInstance().get(cachedEngineId); + this.isFlutterEngineFromHost = true; + if (this.flutterEngine == null) { + throw new Error( + "The requested cached FlutterEngine did not exist in the FlutterEngineCache: '" + + cachedEngineId + + "'"); + } + return; + } + + // Second, defer to subclasses for a custom FlutterEngine. + this.flutterEngine = this.host.provideFlutterEngine(this.context); + if (this.flutterEngine != null) { + this.isFlutterEngineFromHost = true; + return; + } + + // Third, check if the host wants to use a cached FlutterEngineGroup + // and create new FlutterEngine using FlutterEngineGroup#createAndRunEngine + const cachedEngineGroupId = this.host.getCachedEngineGroupId(); + Log.d(TAG, "cachedEngineGroupId=" + cachedEngineGroupId); + if (cachedEngineGroupId != null) { + const flutterEngineGroup = FlutterEngineGroupCache.instance.get(cachedEngineGroupId); + if (flutterEngineGroup == null) { + throw new Error( + "The requested cached FlutterEngineGroup did not exist in the FlutterEngineGroupCache: '" + + cachedEngineGroupId + + "'"); + } + + this.flutterEngine = await flutterEngineGroup.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context))); + this.isFlutterEngineFromHost = false; + return; + } + + // Our host did not provide a custom FlutterEngine. Create a FlutterEngine to back our + // FlutterView. + Log.d( + TAG, + "No preferred FlutterEngine was provided. Creating a new FlutterEngine for this FlutterAbility."); + + let group = this.engineGroup; + if (group == null) { + group = new FlutterEngineGroup(); + await group.checkLoader(this.context, this.host.getFlutterShellArgs().toArray()); + } + this.flutterEngine = await group.createAndRunEngineByOptions(this.addEntrypointOptions(new Options(this.context) + .setAutomaticallyRegisterPlugins(false).setWaitForRestorationData(this.host.shouldRestoreAndSaveState()))); + this.isFlutterEngineFromHost = false; + } + + addEntrypointOptions(options: Options): Options { + let appBundlePathOverride = this.host.getAppBundlePath(); + if (appBundlePathOverride == null || appBundlePathOverride.length == 0) { + appBundlePathOverride = FlutterInjector.getInstance().getFlutterLoader().findAppBundlePath(); + } + + const dartEntrypoint = new DartEntrypoint(appBundlePathOverride, null, this.host.getDartEntrypointFunctionName()); + let initialRoute = this.host.getInitialRoute(); + if (initialRoute == null) { + initialRoute = this.maybeGetInitialRouteFromIntent(this.host.getWant()); + if (initialRoute == null) { + initialRoute = FlutterAbilityLaunchConfigs.DEFAULT_INITIAL_ROUTE; + } + } + return options + .setDartEntrypoint(dartEntrypoint) + .setInitialRoute(initialRoute) + .setDartEntrypointArgs(this.host.getDartEntrypointArgs()); + } + + /** + * 释放所有持有对象 + */ + release() { + this.host = null; + this.flutterEngine = null; + } + + onDetach() { + if (this.host.shouldAttachEngineToActivity()) { + // Notify plugins that they are no longer attached to an Activity. + Log.d(TAG, "Detaching FlutterEngine from the Ability"); + this.flutterEngine.getAbilityControlSurface().detachFromAbility(); + } + } + + onLowMemory(): void { + this.getFlutterNapi().notifyLowMemoryWarning(); + this.flutterEngine.getSystemChannel().sendMemoryPressureWarning(); + } + + /** + * 生命周期回调 + */ + + onCreate() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsInactive(); + } + } + + onDestroy() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsDetached(); + } + this.textInputPlugin.detach(); + } + + onWindowStageCreate() { + this.ensureAlive(); + this.doInitialFlutterViewRun(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onWindowStageDestroy() { + + } + + onWindowFocusChanged(hasFocus: boolean):void { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getAbilityControlSurface().onWindowFocusChanged(hasFocus); + if (hasFocus) { + this.flutterEngine.getLifecycleChannel().aWindowIsFocused(); + } else { + this.flutterEngine.getLifecycleChannel().noWindowsAreFocused(); + } + } + } + + onForeground() { + this.ensureAlive(); + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsResumed(); + } + } + + onBackground() { + if (this.shouldDispatchAppLifecycleState()) { + this.flutterEngine.getLifecycleChannel().appIsPaused(); + } + } + + /** + * 生命周期回调结束 + */ + + shouldDispatchAppLifecycleState(): boolean { + return this.host.shouldDispatchAppLifecycleState() && this.isAttached; + } + + ensureAlive() { + if (this.host == null) { + throw new Error("Cannot execute method on a destroyed FlutterAbilityDelegate."); + } + } + + getFlutterNapi() { + return this.flutterEngine.getFlutterNapi() + } + + detachFromFlutterEngine() { + if (this.host.shouldDestroyEngineWithHost()) { + // The host owns the engine and should never have its engine taken by another exclusive + // activity. + throw new Error( + "The internal FlutterEngine created by " + + this.host + + " has been attached to by another activity. To persist a FlutterEngine beyond the " + + "ownership of this ablity, explicitly create a FlutterEngine"); + } + + // Default, but customizable, behavior is for the host to call {@link #onDetach} + // deterministically as to not mix more events during the lifecycle of the next exclusive + // activity. + this.host.detachFromFlutterEngine(); + } + + getAppComponent(): UIAbility { + const ability = this.host.getAbility(); + if (ability == null) { + throw new Error( + "FlutterActivityAndFragmentDelegate's getAppComponent should only " + + "be queried after onAttach, when the host's ability should always be non-null"); + } + return ability; + } + + onNewWant(want: Want, launchParams: AbilityConstant.LaunchParam): void { + this.ensureAlive() + if (this.flutterEngine != null) { + Log.i(TAG, "Forwarding onNewWant() to FlutterEngine and sending pushRouteInformation message."); + this.flutterEngine.getAbilityControlSurface().onNewWant(want, launchParams); + const initialRoute = this.maybeGetInitialRouteFromIntent(want); + if (initialRoute && initialRoute.length > 0) { + this.flutterEngine.getNavigationChannel().pushRouteInformation(initialRoute); + } + } else { + Log.w(TAG, "onNewIntent() invoked before FlutterFragment was attached to an Activity."); + } + } + + onSaveState(reason: AbilityConstant.StateType, wantParam: Record): AbilityConstant.OnSaveResult { + Log.i(TAG, "onSaveInstanceState. Giving framework and plugins an opportunity to save state."); + this.ensureAlive(); + if (this.host.shouldRestoreAndSaveState()) { + wantParam[FRAMEWORK_RESTORATION_BUNDLE_KEY] = this.flutterEngine.getRestorationChannel().getRestorationData(); + } + if (this.host.shouldAttachEngineToActivity()) { + const plugins:Record = {} + const result = this.flutterEngine.getAbilityControlSurface().onSaveState(reason, plugins); + wantParam[PLUGINS_RESTORATION_BUNDLE_KEY] = plugins; + return result + } + return AbilityConstant.OnSaveResult.ALL_REJECT + } + + addPlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().add(plugin) + } + + removePlugin(plugin: FlutterPlugin): void { + this.flutterEngine.getPlugins().remove(plugin.getUniqueClassName()) + } + + sendSettings(): void { + this.settings.sendSettings() + } +} + + +/** + * FlutterAbility句柄 + */ +interface Host extends FlutterEngineProvider, FlutterEngineConfigurator, PlatformPluginDelegate, MouseCursorViewDelegate { + + getAbility(): UIAbility; + + loadContent():void; + + shouldDispatchAppLifecycleState(): boolean; + + detachFromFlutterEngine(); + + shouldAttachEngineToActivity(): boolean; + + getCachedEngineId(): string; + + getCachedEngineGroupId(): string; + + /** + * Returns true if the {@link io.flutter.embedding.engine.FlutterEngine} used in this delegate + * should be destroyed when the host/delegate are destroyed. + */ + shouldDestroyEngineWithHost(): boolean; + + /** Returns the {@link FlutterShellArgs} that should be used when initializing Flutter. */ + getFlutterShellArgs(): FlutterShellArgs; + + /** Returns arguments that passed as a list of string to Dart's entrypoint function. */ + getDartEntrypointArgs(): Array; + + /** + * Returns the URI of the Dart library which contains the entrypoint method (example + * "package:foo_package/main.dart"). If null, this will default to the same library as the + * `main()` function in the Dart program. + */ + getDartEntrypointLibraryUri(): string; + + /** Returns the path to the app bundle where the Dart code exists. */ + getAppBundlePath(): string; + + /** + * Returns the Dart entrypoint that should run when a new {@link + * io.flutter.embedding.engine.FlutterEngine} is created. + */ + getDartEntrypointFunctionName(): string; + + /** Returns the initial route that Flutter renders. */ + getInitialRoute(): string; + + getWant(): Want; + + shouldRestoreAndSaveState(): boolean; +} + +export { Host, FlutterAbilityDelegate } \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets new file mode 100644 index 0000000000000000000000000000000000000000..996f455b9d045411425025f5c68089aee3f8938c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterAbilityLaunchConfigs.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** The mode of the background of a Flutter {@code Activity}, either opaque or transparent. */ +enum BackgroundMode { + /** Indicates a FlutterActivity with an opaque background. This is the default. */ + opaque, + /** Indicates a FlutterActivity with a transparent background. */ + transparent +} + +export default class FlutterAbilityLaunchConfigs { + + static DART_ENTRYPOINT_META_DATA_KEY = "io.flutter.Entrypoint"; + static DART_ENTRYPOINT_URI_META_DATA_KEY = "io.flutter.EntrypointUri"; + static INITIAL_ROUTE_META_DATA_KEY = "io.flutter.InitialRoute"; + static SPLASH_SCREEN_META_DATA_KEY = "io.flutter.embedding.android.SplashScreenDrawable"; + static NORMAL_THEME_META_DATA_KEY = "io.flutter.embedding.android.NormalTheme"; + static HANDLE_DEEPLINKING_META_DATA_KEY = "flutter_deeplinking_enabled"; + // Intent extra arguments. + static EXTRA_DART_ENTRYPOINT = "dart_entrypoint"; + static EXTRA_INITIAL_ROUTE = "route"; + static EXTRA_BACKGROUND_MODE = "background_mode"; + static EXTRA_CACHED_ENGINE_ID = "cached_engine_id"; + static EXTRA_DART_ENTRYPOINT_ARGS = "dart_entrypoint_args"; + static EXTRA_CACHED_ENGINE_GROUP_ID = "cached_engine_group_id"; + static EXTRA_DESTROY_ENGINE_WITH_ACTIVITY = "destroy_engine_with_activity"; + static EXTRA_ENABLE_STATE_RESTORATION = "enable_state_restoration"; + + // Default configuration. + static DEFAULT_DART_ENTRYPOINT = "main"; + static DEFAULT_INITIAL_ROUTE = "/"; + static DEFAULT_BACKGROUND_MODE = BackgroundMode.opaque +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets new file mode 100644 index 0000000000000000000000000000000000000000..7953cad0836a9be4bf6bfd940594fdc787f45d66 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineConfigurator.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; + +export default interface FlutterEngineConfigurator { + + configureFlutterEngine(flutterEngine: FlutterEngine); + + cleanUpFlutterEngine(flutterEngine: FlutterEngine); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets new file mode 100644 index 0000000000000000000000000000000000000000..1bdd7b6a809a77510f8942e81e0d91e7b4970893 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterEngineProvider.ets @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterEngine from '../engine/FlutterEngine'; +import common from '@ohos.app.ability.common'; + +export default interface FlutterEngineProvider { + provideFlutterEngine(context: common.Context): FlutterEngine; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets new file mode 100644 index 0000000000000000000000000000000000000000..05695111937b486f3f498e9c87c12bdb85d829c5 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/FlutterPage.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import { PlatformViewWrapper } from '../../plugin/platform/PlatformViewWrapper'; +import { RootDvModeManager } from '../../plugin/platform/RootDvModelManager'; +import { DVModel, + DVModelChildren, + DVModelContainer, + DVModelEvents, + DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +/** + * 基础page组件,承载XComponent组件 + */ +@Component +export struct FlutterPage { + @State message: string = 'Hello World'; + + @State rootDvModel: DVModelContainer = RootDvModeManager.getRootDvMode(); + + build() { + DynamicView({ + model: this.rootDvModel.model as DVModel, + params: this.rootDvModel.model.params as DVModelParameters, + events: this.rootDvModel.model.events as DVModelEvents, + children: this.rootDvModel.model.children as DVModelChildren, + customBuilder: this.rootDvModel.model.builder as ($$: Record<"params",DVModelParameters >) => void + //customBuilder: this.rootDvModel.model.builder as ($$: { params: DVModelParameters }) => void + }) + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets new file mode 100644 index 0000000000000000000000000000000000000000..53f0f0a6c8f5e2ec858ad802a4e4653ed164c31e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/OhosTouchProcessor.ets @@ -0,0 +1,58 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; + +export default class OhosTouchProcessor { + private static POINTER_DATA_FIELD_COUNT: number = 35; + + static BYTES_PER_FIELD: number = 8; + + private static POINTER_DATA_FLAG_BATCHED: number = 1; + + public onTouchEvent(event: TouchEvent, transformMatrix: ESObject): void { + + } +} + +export enum PointerChange { + CANCEL = 0, + ADD = 1, + REMOVE = 2, + HOVER = 3, + DOWN = 4, + MOVE = 5, + UP = 6, + PAN_ZOOM_START = 7, + PAN_ZOOM_UPDATE = 8, + PAN_ZOOM_END = 9 +} + +export enum PointerDeviceKind { + TOUCH = 0, + MOUSE = 1, + STYLUS = 2, + INVERTED_STYLUS = 3, + TRACKPAD = 4, + UNKNOWN = 5 +} + +export enum PointerSignalKind { + NONE = 0, + SCROLL = 1, + SCROLL_INERTIA_CANCEL = 2, + SCALE = 3, + UNKNOWN = 4 +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets new file mode 100644 index 0000000000000000000000000000000000000000..a435d2a45cc960a5d6a4eb49c3d131c83b4d2dcb --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/Settings.ets @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import SettingsChannel, { PlatformBrightness } from '../engine/systemchannels/SettingsChannel' +import I18n from '@ohos.i18n' + +export default class Settings { + settingsChannel: SettingsChannel; + + constructor(settingsChannel: SettingsChannel) { + this.settingsChannel = settingsChannel; + } + + sendSettings(): void { + this.settingsChannel.startMessage() + .setAlwaysUse24HourFormat(I18n.System.is24HourClock()) + .setTextScaleFactor(1.0) + .setNativeSpellCheckServiceDefined(false) + .setBrieflyShowPassword(false) + .setPlatformBrightness(PlatformBrightness.LIGHT) + .send(); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets new file mode 100644 index 0000000000000000000000000000000000000000..15814be043c938ddca9560390fad99d6b15a23c3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/TouchEventTracker.ets @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** Tracks the motion events received by the FlutterView. */ +import PlainArray from '@ohos.util.PlainArray'; +import { TouchEvent } from '@ohos.multimodalInput.touchEvent'; +import Queue from '@ohos.util.Queue'; + +export class TouchEventTracker { + private eventById : PlainArray; + private unusedEvents : Queue; + private static INSTANCE:TouchEventTracker; + + public static getInstance(): TouchEventTracker { + if (TouchEventTracker.INSTANCE == null) { + TouchEventTracker.INSTANCE = new TouchEventTracker(); + } + return TouchEventTracker.INSTANCE; + } + + constructor() { + this.eventById = new PlainArray(); + this.unusedEvents = new Queue(); + } + + /** Tracks the event and returns a unique MotionEventId identifying the event. */ + public track(event :TouchEvent) : TouchEventId { + const eventId:TouchEventId = TouchEventId.createUnique(); + this.eventById.add(eventId.getId(), event); + this.unusedEvents.add(eventId.getId()); + return eventId; + } + + /** + * Returns the MotionEvent corresponding to the eventId while discarding all the motion events + * that occurred prior to the event represented by the eventId. Returns null if this event was + * popped or discarded. + */ + public pop(eventId : TouchEventId) : TouchEvent { + // remove all the older events. + while (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() < eventId.getId()) { + this.eventById.remove(this.unusedEvents.pop()); + } + + // remove the current event from the heap if it exists. + if (this.unusedEvents.length != 0 && this.unusedEvents.getFirst() == eventId.getId()) { + this.unusedEvents.pop(); + } + + const event : TouchEvent = this.eventById.get(eventId.getId()); + this.eventById.remove(eventId.getId()); + return event; + } +} + +/** Represents a unique identifier corresponding to a motion event. */ +export class TouchEventId { + private static ID_COUNTER : number = 0; + private id : number; + + constructor(id : number) { + this.id = id; + } + + public static from(id : number) : TouchEventId { + return new TouchEventId(id); + } + + public static createUnique() : TouchEventId { + return new TouchEventId(TouchEventId.ID_COUNTER++); + } + + public getId() : number { + return this.id; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..ae2c6cfd5202c3f2c912720217df452a727f35b6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/embedding/ohos/WindowInfoRepositoryCallbackAdapterWrapper.ets @@ -0,0 +1,23 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; + +export default class WindowInfoRepositoryCallbackAdapterWrapper { + + constructor() { + } + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..9910f14b6d71e2fc70e55eb8c7846ccbeffa0180 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/PlatformPlugin.ets @@ -0,0 +1,301 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import PlatformChannel, { + AppSwitcherDescription, + Brightness, + ClipboardContentFormat, + HapticFeedbackType, + PlatformMessageHandler, + SoundType, + SystemChromeStyle, + SystemUiMode, + SystemUiOverlay +} from '../embedding/engine/systemchannels/PlatformChannel'; +import pasteboard from '@ohos.pasteboard'; +import Log from '../util/Log'; +import vibrator from '@ohos.vibrator'; +import window from '@ohos.window'; +import common from '@ohos.app.ability.common'; + +/** + * ohos实现platform plugin + */ +export default class PlatformPlugin { + private static TAG = "PlatformPlugin"; + private callback = new PlatformPluginCallback(); + + constructor(platformChannel: PlatformChannel, context: common.Context, platformPluginDelegate?: PlatformPluginDelegate) { + this.callback.platformChannel = platformChannel; + this.callback.context = context; + this.callback.applicationContext = context.getApplicationContext(); + this.callback.platform = this; + + try { + window.getLastWindow(context, (err, data) => { + if (err.code) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + return; + } + this.callback.windowClass = data; + }); + } catch (err) { + Log.e(PlatformPlugin.TAG, "Failed to obtain the top window. Cause: " + JSON.stringify(err)); + } + this.callback.platformPluginDelegate = platformPluginDelegate; + this.callback.platformChannel.setPlatformMessageHandler(this.callback); + } + + + updateSystemUiOverlays(): void { + this.callback.windowClass.setWindowSystemBarEnable(this.callback.showBarOrNavigation); + if (this.callback.currentTheme != null) { + this.callback.setSystemChromeSystemUIOverlayStyle(this.callback.currentTheme); + } + } + + setUIAbilityContext(context: common.UIAbilityContext): void { + this.callback.uiAbilityContext = context; + } + + setSystemChromeChangeListener(): void { + if (this.callback.callbackId == null && this.callback.applicationContext != null) { + let that = this; + this.callback.callbackId = this.callback.applicationContext.on('environment', { + onConfigurationUpdated(config) { + Log.d(PlatformPlugin.TAG, "onConfigurationUpdated: " + that.callback.showBarOrNavigation); + that.callback.platformChannel.systemChromeChanged(that.callback.showBarOrNavigation.includes('status')); + }, + onMemoryLevel(level) { + } + }) + } + } +} + +export interface PlatformPluginDelegate { + popSystemNavigator(): boolean; +} + +class PlatformPluginCallback implements PlatformMessageHandler { + private static TAG = "PlatformPluginCallback"; + platform: PlatformPlugin; + windowClass: window.Window = null; + platformChannel: PlatformChannel; + platformPluginDelegate: PlatformPluginDelegate; + context: common.Context; + showBarOrNavigation: ('status' | 'navigation')[] = ['status', 'navigation']; + uiAbilityContext: common.UIAbilityContext = null; + callbackId: number = null; + applicationContext: common.ApplicationContext = null; + currentTheme: SystemChromeStyle = null; + + playSystemSound(soundType: SoundType) { + } + + vibrateHapticFeedback(feedbackType: HapticFeedbackType) { + switch (feedbackType) { + case HapticFeedbackType.STANDARD: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'touch' }); + break; + case HapticFeedbackType.LIGHT_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'notification' }).then(); + break; + case HapticFeedbackType.MEDIUM_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'ring' }); + break; + case HapticFeedbackType.HEAVY_IMPACT: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'alarm' }); + break; + case HapticFeedbackType.SELECTION_CLICK: + vibrator.startVibration({ type: 'time', duration: 100 }, + { id: 0, usage: 'physicalFeedback' }); + break; + } + } + + setPreferredOrientations(ohosOrientation: number) { + Log.d(PlatformPluginCallback.TAG, "ohosOrientation: " + ohosOrientation); + this.windowClass.setPreferredOrientation(ohosOrientation); + } + + setApplicationSwitcherDescription(description: AppSwitcherDescription) { + // representation described in the given {@code description}. + } + + showSystemOverlays(overlays: SystemUiOverlay[]) { + this.setSystemChromeEnabledSystemUIOverlays(overlays); + } + + showSystemUiMode(mode: SystemUiMode) { + this.setSystemChromeEnabledSystemUIMode(mode); + } + + setSystemUiChangeListener() { + this.platform.setSystemChromeChangeListener(); + } + + restoreSystemUiOverlays() { + this.platform.updateSystemUiOverlays(); + } + + setSystemUiOverlayStyle(systemUiOverlayStyle: SystemChromeStyle) { + Log.d(PlatformPluginCallback.TAG, "systemUiOverlayStyle:" + JSON.stringify(systemUiOverlayStyle)); + this.setSystemChromeSystemUIOverlayStyle(systemUiOverlayStyle); + } + + popSystemNavigator() { + if (this.platformPluginDelegate != null && this.platformPluginDelegate.popSystemNavigator()) { + return; + } + if (this.uiAbilityContext != null) { + this.uiAbilityContext.terminateSelf(); + } + } + + getClipboardData(format: ClipboardContentFormat): string { + // todo + return ""; + } + + setClipboardData(text: string) { + let pasteData = pasteboard.createData(pasteboard.MIMETYPE_TEXT_PLAIN, text); + let clipboard = pasteboard.getSystemPasteboard(); + clipboard.setData(pasteData); + } + + clipboardHasStrings(): boolean { + return false; + } + + setSystemChromeEnabledSystemUIMode(mode: SystemUiMode): void { + Log.d(PlatformPluginCallback.TAG, "mode: " + mode); + let uiConfig: ('status' | 'navigation')[] = []; + if (mode == SystemUiMode.LEAN_BACK) { + //全屏显示,通过点击显示器上的任何位置都可以显示状态和导航栏 + this.windowClass.setWindowLayoutFullScreen(false); + + } else if (mode == SystemUiMode.IMMERSIVE) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,应用程序不会接收到此手势 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.IMMERSIVE_STICKY) { + //全屏显示,通过在显示器边缘的滑动手势可以显示状态和导航栏,此手势由应用程序接收 + this.windowClass.setWindowLayoutFullScreen(true); + + } else if (mode == SystemUiMode.EDGE_TO_EDGE) { + //全屏显示,在应用程序上呈现状态和导航元素 + this.windowClass.setWindowLayoutFullScreen(false); + uiConfig = ['status', 'navigation']; + + } else { + return; + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } + + setSystemChromeSystemUIOverlayStyle(systemChromeStyle: SystemChromeStyle): void { + let isStatusBarLightIconValue: boolean = false; + let statusBarColorValue: string = null; + let statusBarContentColorValue: string = null; + let navigationBarColorValue: string = null; + let isNavigationBarLightIconValue: boolean = false; + let navigationBarContentColorValue: string = null; + if (systemChromeStyle.statusBarIconBrightness != null) { + switch (systemChromeStyle.statusBarIconBrightness) { + case Brightness.DARK: + isStatusBarLightIconValue = false; + break; + case Brightness.LIGHT: + isStatusBarLightIconValue = true; + break; + } + } + + if (systemChromeStyle.statusBarColor != null) { + statusBarColorValue = "#" + systemChromeStyle.statusBarColor.toString(16); + } + + if (systemChromeStyle.systemStatusBarContrastEnforced != null) { + + } + + if (systemChromeStyle.systemNavigationBarIconBrightness != null) { + switch (systemChromeStyle.systemNavigationBarIconBrightness) { + case Brightness.DARK: + isNavigationBarLightIconValue = true; + break; + case Brightness.LIGHT: + isNavigationBarLightIconValue = false; + } + } + + if (systemChromeStyle.systemNavigationBarColor != null) { + navigationBarColorValue = "#" + systemChromeStyle.systemNavigationBarColor.toString(16); + } + + if (systemChromeStyle.systemNavigationBarContrastEnforced != null) { + + } + this.currentTheme = systemChromeStyle; + let systemBarProperties = new SystemBarProperties(); + systemBarProperties.statusBarColor = statusBarColorValue; + systemBarProperties.isStatusBarLightIcon = isStatusBarLightIconValue; + systemBarProperties.statusBarContentColor = statusBarContentColorValue; + systemBarProperties.navigationBarColor = navigationBarColorValue; + systemBarProperties.isNavigationBarLightIcon = isNavigationBarLightIconValue; + systemBarProperties.navigationBarContentColor = navigationBarContentColorValue; + Log.d(PlatformPluginCallback.TAG, "systemBarProperties: " + JSON.stringify(systemBarProperties)); + this.windowClass.setWindowSystemBarProperties(systemBarProperties); + } + + setSystemChromeEnabledSystemUIOverlays(overlays: SystemUiOverlay[]): void { + let uiConfig: ('status' | 'navigation')[] = []; + if (overlays.length == 0) { + + } + for (let index = 0; index < overlays.length; ++index) { + let overlayToShow = overlays[index]; + switch (overlayToShow) { + case SystemUiOverlay.TOP_OVERLAYS: + uiConfig.push('status'); //hide navigation + break; + case SystemUiOverlay.BOTTOM_OVERLAYS: + uiConfig.push('navigation'); //hide bar + break; + } + } + this.showBarOrNavigation = uiConfig; + this.platform.updateSystemUiOverlays(); + } +} + +class SystemBarProperties { + statusBarColor?: string; + + isStatusBarLightIcon?: boolean; + + statusBarContentColor?: string; + + navigationBarColor?: string; + + isNavigationBarLightIcon?: boolean; + + navigationBarContentColor?: string; +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..a6e6f6bcfb5b863a2b5c65b9f398ec5e048f4ad6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel.ets @@ -0,0 +1,170 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler } from './BinaryMessenger'; +import Log from '../../util/Log'; +import { BinaryReply } from './BinaryMessenger'; +import { TaskQueue } from './BinaryMessenger'; +import MessageCodec from './MessageCodec'; +import { BinaryMessenger } from './BinaryMessenger'; +/** + * A named channel for communicating with the Flutter application using basic, asynchronous message + * passing. + * + *

Messages are encoded into binary before being sent, and binary messages received are decoded + * into Java objects. The {@link MessageCodec} used must be compatible with the one used by the + * Flutter application. This can be achieved by creating a BasicMessageChannel + * counterpart of this channel on the Dart side. The static Java type of messages sent and received + * is {@code Object}, but only values supported by the specified {@link MessageCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +export default class BasicMessageChannel { + public static TAG = "BasicMessageChannel#"; + public static CHANNEL_BUFFERS_CHANNEL = "dev.flutter/channel-buffers"; + private messenger: BinaryMessenger; + private name: string; + private codec: MessageCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MessageCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Sends the specified message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param message the message, possibly null. + * @param callback a {@link Reply} callback, possibly null. + */ + send(message: T, callback?: (reply: T)=>void): void { + this.messenger.send(this.name, this.codec.encodeMessage(message), callback == null ? null : new IncomingReplyHandler(callback, this.codec)); + } + + /** + * Registers a message handler on this channel for receiving messages sent from the Flutter + * application. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming message on this channel will be handled + * silently by sending a null reply. + * + * @param handler a {@link MessageHandler}, or null to deregister. + */ + setMessageHandler(handler: MessageHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler(this.name, handler == null ? null : new IncomingMessageHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + + +export interface Reply { + /** + * Handles the specified message reply. + * + * @param reply the reply, possibly null. + */ + reply: (reply: T) => void; +} + +export interface MessageHandler { + + /** + * Handles the specified message received from Flutter. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link Reply}. Failure to do so will result in lingering Flutter reply + * handlers. The reply may be submitted asynchronously and invoked on any thread. + * + *

Any uncaught exception thrown by this method, or the preceding message decoding, will be + * caught by the channel implementation and logged, and a null reply message will be sent back + * to Flutter. + * + *

Any uncaught exception thrown during encoding a reply message submitted to the {@link + * Reply} is treated similarly: the exception is logged, and a null reply is sent to Flutter. + * + * @param message the message, possibly null. + * @param reply a {@link Reply} for sending a single message reply back to Flutter. + */ + onMessage(message: T, reply: Reply): void; +} + +class IncomingReplyHandler implements BinaryReply { + private callback: (reply: T)=>void; + private codec: MessageCodec + + constructor(callback:(reply: T)=>void, codec: MessageCodec) { + this.callback = callback + this.codec = codec + } + + reply(reply: ArrayBuffer) { + try { + this.callback(this.codec.decodeMessage(reply)); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message reply", e); + } + } +} + +class IncomingMessageHandler implements BinaryMessageHandler { + private handler: MessageHandler + private codec: MessageCodec + + constructor(handler: MessageHandler, codec: MessageCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, callback: BinaryReply) { + try { + this.handler.onMessage( + this.codec.decodeMessage(message), + { + reply: (reply: T): void => { + callback.reply(this.codec.encodeMessage(reply)); + } + }); + } catch (e) { + Log.e(BasicMessageChannel.TAG, "Failed to handle message", e); + callback.reply(null); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..578436417dc4a23cfaf2c5adbb9c8340efa5795d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryCodec.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using unencoded binary messages, represented as {@link ByteBuffer}s. + * + *

This codec is guaranteed to be compatible with the corresponding BinaryCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, messages are represented using {@code ByteData}. + */ + +export default class BinaryCodec implements MessageCodec { + private returnsDirectByteBufferFromDecoding: boolean = false; + static readonly INSTANCE_DIRECT = new BinaryCodec(true); + + constructor(returnsDirectByteBufferFromDecoding: boolean) { + this.returnsDirectByteBufferFromDecoding = returnsDirectByteBufferFromDecoding; + } + + encodeMessage(message: ArrayBuffer): ArrayBuffer { + return message + } + + decodeMessage(message: ArrayBuffer): ArrayBuffer { + if (message == null) { + return message; + } else if (this.returnsDirectByteBufferFromDecoding) { + return message; + } else { + return message.slice(0, message.byteLength); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets new file mode 100644 index 0000000000000000000000000000000000000000..988c6a57092f7913f20b65bf6afa97b310385931 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger.ets @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * An abstraction over the threading policy used to invoke message handlers. + * + *

These are generated by calling methods like {@link + * BinaryMessenger#makeBackgroundTaskQueue(TaskQueueOptions)} and can be passed into platform + * channels' constructors to control the threading policy for handling platform channels' + * messages. + */ +export interface TaskQueue {} + +/** Options that control how a TaskQueue should operate and be created. */ +export class TaskQueueOptions { + private isSerial = true; + + getIsSerial() { + return this.isSerial; + } + + setIsSerial(isSerial: boolean): TaskQueueOptions { + this.isSerial = isSerial; + return this; + } +} + +/** + * Binary message reply callback. Used to submit a reply to an incoming message from Flutter. Also + * used in the dual capacity to handle a reply received from Flutter after sending a message. + */ +export interface BinaryReply { + /** + * Handles the specified reply. + * + * @param reply the reply payload, a direct-allocated {@link ByteBuffer} or null. Senders of + * outgoing replies must place the reply bytes between position zero and current position. + * Reply receivers can read from the buffer directly. + */ + reply(reply: ArrayBuffer): void; +} + +/** Handler for incoming binary messages from Flutter. */ +export interface BinaryMessageHandler { + /** + * Handles the specified message. + * + *

Handler implementations must reply to all incoming messages, by submitting a single reply + * message to the given {@link BinaryReply}. Failure to do so will result in lingering Flutter + * reply handlers. The reply may be submitted asynchronously. + * + *

Any uncaught exception thrown by this method will be caught by the messenger + * implementation and logged, and a null reply message will be sent back to Flutter. + * + * @param message the message {@link ByteBuffer} payload, possibly null. + * @param reply A {@link BinaryReply} used for submitting a reply back to Flutter. + */ + onMessage(message: ArrayBuffer, reply: BinaryReply): void; +} + +/** + * Facility for communicating with Flutter using asynchronous message passing with binary messages. + * The Flutter Dart code should use BinaryMessages to + * participate. + * + *

{@code BinaryMessenger} is expected to be utilized from a single thread throughout the + * duration of its existence. If created on the main thread, then all invocations should take place + * on the main thread. If created on a background thread, then all invocations should take place on + * that background thread. + * + * @see BasicMessageChannel , which supports message passing with Strings and semi-structured + * messages. + * @see MethodChannel , which supports communication using asynchronous method invocation. + * @see EventChannel , which supports communication using event streams. + */ +export interface BinaryMessenger { + makeBackgroundTaskQueue(options?: TaskQueueOptions): TaskQueue; + + /** + * Sends a binary message to the Flutter application. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + */ + send(channel: String, message: ArrayBuffer): void; + + /** + * Sends a binary message to the Flutter application, optionally expecting a reply. + * + *

Any uncaught exception thrown by the reply callback will be caught and logged. + * + * @param channel the name {@link String} of the logical channel used for the message. + * @param message the message payload, a direct-allocated {@link ByteBuffer} with the message + * bytes between position zero and current position, or null. + * @param callback a {@link BinaryReply} callback invoked when the Flutter application responds to + * the message, possibly null. + */ + send(channel: String, message: ArrayBuffer, callback?: BinaryReply): void; + + /** + * Registers a handler to be invoked when the Flutter application sends a message to its host + * platform. + * + *

Registration overwrites any previous registration for the same channel name. Use a null + * handler to deregister. + * + *

If no handler has been registered for a particular channel, any incoming message on that + * channel will be handled silently by sending a null reply. + * + * @param channel the name {@link String} of the channel. + * @param handler a {@link BinaryMessageHandler} to be invoked on incoming messages, or null. + * @param taskQueue a {@link BinaryMessenger.TaskQueue} that specifies what thread will execute + * the handler. Specifying null means execute on the platform thread. + */ + //setMessageHandler(channel: String, handler: BinaryMessageHandler) + setMessageHandler(channel: String, handler: BinaryMessageHandler, taskQueue?: TaskQueue): void; + // { + // if (taskQueue != null) { + // throw new Error("setMessageHandler called with nonnull taskQueue is not supported.") + // } + // } + + /** + * Enables the ability to queue messages received from Dart. + * + *

This is useful when there are pending channel handler registrations. For example, Dart may + * be initialized concurrently, and prior to the registration of the channel handlers. This + * implies that Dart may start sending messages while plugins are being registered. + */ + enableBufferingIncomingMessages(): void; + // { + // throw new Error("enableBufferingIncomingMessages not implemented."); + // } + + /** + * Disables the ability to queue messages received from Dart. + * + *

This can be used after all pending channel handlers have been registered. + */ + disableBufferingIncomingMessages(): void; + // { + // throw new Error("disableBufferingIncomingMessages not implemented."); + // } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..166659a32e819580f2d433886f763dc453d8a597 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/EventChannel.ets @@ -0,0 +1,263 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +/** + * A named channel for communicating with the Flutter application using asynchronous event streams. + * + *

Incoming requests for event stream setup are decoded from binary on receipt, and Java + * responses and events are encoded into binary before being transmitted back to Flutter. The {@link + * MethodCodec} used must be compatible with the one used by the Flutter application. This can be + * achieved by creating an EventChannel + * counterpart of this channel on the Dart side. The Java type of stream configuration arguments, + * events, and error details is {@code Object}, but only values supported by the specified {@link + * MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ +import Log from '../../util/Log'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; + +const TAG = "EventChannel#"; + +export default class EventChannel { + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec?: MethodCodec, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec ? codec : StandardMethodCodec.INSTANCE + this.taskQueue = taskQueue + } + + + /** + * Registers a stream handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming stream setup requests will be handled + * silently by providing an empty stream. + * + * @param handler a {@link StreamHandler}, or null to deregister. + */ + setStreamHandler(handler: StreamHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingStreamRequestHandler(handler, this.name, this.codec, this.messenger)); + } + } +} + +/** + * Handler of stream setup and teardown requests. + * + *

Implementations must be prepared to accept sequences of alternating calls to {@link + * #onListen(Object, EventChannel.EventSink)} and {@link #onCancel(Object)}. Implementations + * should ideally consume no resources when the last such call is not {@code onListen}. In typical + * situations, this means that the implementation should register itself with platform-specific + * event sources {@code onListen} and deregister again {@code onCancel}. + */ +export interface StreamHandler { + /** + * Handles a request to set up an event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + * @param arguments stream configuration arguments, possibly null. + * @param events an {@link EventSink} for emitting events to the Flutter receiver. + */ + onListen(args: ESObject, events: EventSink): void; + + /** + * Handles a request to tear down the most recently created event stream. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged. An error result message will be sent back to Flutter. + * + *

The channel implementation may call this method with null arguments to separate a pair of + * two consecutive set up requests. Such request pairs may occur during Flutter hot restart. Any + * uncaught exception thrown in this situation will be logged without notifying Flutter. + * + * @param arguments stream configuration arguments, possibly null. + */ + onCancel(args: ESObject): void; +} + +/** + * Event callback. Supports dual use: Producers of events to be sent to Flutter act as clients of + * this interface for sending events. Consumers of events sent from Flutter implement this + * interface for handling received events (the latter facility has not been implemented yet). + */ +export interface EventSink { + /** + * Consumes a successful event. + * + * @param event the event, possibly null. + */ + success(event: ESObject): void; + + /** + * Consumes an error event. + * + * @param errorCode an error code String. + * @param errorMessage a human-readable error message String, possibly null. + * @param errorDetails error details, possibly null + */ + error(errorCode: string, errorMessage: string, errorDetails: ESObject): void; + + /** + * Consumes end of stream. Ensuing calls to {@link #success(Object)} or {@link #error(String, + * String, Object)}, if any, are ignored. + */ + endOfStream(): void; +} + +class IncomingStreamRequestHandler implements BinaryMessageHandler { + private handler: StreamHandler; + private activeSink = new AtomicReference(null); + private codec: MethodCodec; + private name: string; + private messenger: BinaryMessenger; + + constructor(handler: StreamHandler, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.handler = handler; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + if (call.method == "listen") { + this.onListen(call.args, reply); + } else if (call.method == "cancel") { + this.onCancel(call.args, reply); + } else { + reply.reply(null); + } + } + + onListen(args: ESObject, callback: BinaryReply): void { + const eventSink = new EventSinkImplementation(this.activeSink, this.name, this.codec, this.messenger); + const oldSink = this.activeSink.getAndSet(eventSink); + if (oldSink != null) { + // Repeated calls to onListen may happen during hot restart. + // We separate them with a call to onCancel. + try { + this.handler.onCancel(null); + } catch (e) { + Log.e(TAG + this.name, "Failed to close existing event stream", e); + } + } + try { + this.handler.onListen(args, eventSink); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + this.activeSink.set(null); + Log.e(TAG + this.name, "Failed to open event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } + + onCancel(args: ESObject, callback: BinaryReply): void { + const oldSink = this.activeSink.getAndSet(null); + if (oldSink != null) { + try { + this.handler.onCancel(args); + callback.reply(this.codec.encodeSuccessEnvelope(null)); + } catch (e) { + Log.e(TAG + this.name, "Failed to close event stream", e); + callback.reply(this.codec.encodeErrorEnvelope("error", e.getMessage(), null)); + } + } else { + callback.reply(this.codec.encodeErrorEnvelope("error", "No active stream to cancel", null)); + } + } +} + +class EventSinkImplementation implements EventSink { + private hasEnded = false; + private activeSink: AtomicReference; + private messenger: BinaryMessenger; + private codec: MethodCodec; + private name: string; + + constructor(activeSink: AtomicReference, name: string, codec: MethodCodec, messenger: BinaryMessenger) { + this.activeSink = activeSink; + this.codec = codec; + this.name = name; + this.messenger = messenger; + } + + success(event: ESObject): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send(this.name, this.codec.encodeSuccessEnvelope(event)); + } + + error(errorCode: string, errorMessage: string, errorDetails: ESObject) { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.messenger.send( + this.name, this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + } + + endOfStream(): void { + if (this.hasEnded || this.activeSink.get() != this) { + return; + } + this.hasEnded = true; + this.messenger.send(this.name, null); + } +} + +class AtomicReference { + private value: T; + + constructor(value: T) { + this.value = value + } + + get(): T { + return this.value; + } + + set(newValue: T): void { + this.value = newValue; + } + + getAndSet(newValue: T) { + const oldValue = this.value; + this.value = newValue; + return oldValue; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets new file mode 100644 index 0000000000000000000000000000000000000000..03af6b520acc908d9cb63914ca2236736218aa77 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/FlutterException.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterException implements Error { + stack?: string; + message: string; + name: string; + code: string; + details: ESObject + + constructor(code: string, message: string, details: ESObject) { + this.message = message; + this.code = code; + this.details =details; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..4c289c6054e952a5cf7ed48b58fcfab6e343533b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMessageCodec.ets @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from './MessageCodec'; +import MethodCodec from './MethodCodec'; +import StringCodec from './StringCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

On the Dart side, JSON messages are handled by the JSON facilities of the dart:convert package. + */ +export default class JSONMessageCodec implements MessageCodec { + static INSTANCE = new JSONMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + return StringCodec.INSTANCE.encodeMessage(JSON.stringify(message)); + } + + decodeMessage(message: ArrayBuffer): ESObject { + if (message == null) { + return null; + } + try { + const jsonStr = StringCodec.INSTANCE.decodeMessage(message); + return JSON.parse(jsonStr); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..7b5bf1d0891fe841d7380e0e6166ca5b82793e7b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/JSONMethodCodec.ets @@ -0,0 +1,97 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import Log from '../../util/Log'; + +import ToolUtils from '../../util/ToolUtils'; +import FlutterException from './FlutterException'; +import JSONMessageCodec from './JSONMessageCodec'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; + +/** + * A {@link MethodCodec} using UTF-8 encoded JSON method calls and result envelopes. + * + *

This codec is guaranteed to be compatible with the corresponding JSONMethodCodec on + * the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as methods arguments and result payloads are those supported by {@link + * JSONMessageCodec}. + */ +export default class JSONMethodCodec implements MethodCodec { + static INSTANCE = new JSONMethodCodec(); + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + try { + const map: Record = { + "method": methodCall.method, "args": methodCall.args + } + + return JSONMessageCodec.INSTANCE.encodeMessage(map); + } catch (e) { + throw new Error("Invalid JSON"); + } + } + + decodeMethodCall(message: ArrayBuffer): MethodCall { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(message); + if (ToolUtils.isObj(json)) { + const method: string = json["method"]; + const args: ESObject = json["args"]; + if (typeof method == 'string') { + return new MethodCall(method, args); + } + } + throw new Error("Invalid method call: " + json); + } catch (e) { + throw new Error("Invalid JSON:" + JSON.stringify(e)); + } + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([result]); + } + + encodeErrorEnvelope(errorCode: ESObject, errorMessage: string, errorDetails: ESObject) { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails]); + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + return JSONMessageCodec.INSTANCE.encodeMessage([errorCode, errorMessage, errorDetails, errorStacktrace]) + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + try { + const json: ESObject = JSONMessageCodec.INSTANCE.decodeMessage(envelope); + if (json instanceof Array) { + if (json.length == 1) { + return json[0]; + } + if (json.length == 3) { + const code: string = json[0]; + const message: string = json[1]; + const details: ESObject = json[2]; + if (typeof code == 'string' && (message == null || typeof message == 'string')) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Invalid envelope: " + json); + } catch (e) { + throw new Error("Invalid JSON"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..663d57af19c70523e44a5f48cc61e22ab0dc5b33 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec.ets @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/** + * A message encoding/decoding mechanism. + */ +export default interface MessageCodec { + /** + * Encodes the specified message into binary. + */ + encodeMessage(message: T) : ArrayBuffer; + + /** + * Decodes the specified message from binary. + * + */ + decodeMessage(message: ArrayBuffer): T; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets new file mode 100644 index 0000000000000000000000000000000000000000..0042c25c3b21f484cda8158e5485bb57e73dfd82 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCall.ets @@ -0,0 +1,59 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import ToolUtils from '../../util/ToolUtils'; +/** Command object representing a method call on a {@link MethodChannel}. */ +export default class MethodCall { + /** The name of the called method. */ + method: string; + + /** + * Arguments for the call. + * + *

Consider using {@link #arguments()} for cases where a particular run-time type is expected. + * Consider using {@link #argument(String)} when that run-time type is {@link Map} or {@link + * JSONObject}. + */ + args: ESObject; + + constructor(method: string, args: ESObject) { + this.method = method + this.args = args + } + + argument(key: string): ESObject { + if (this.args == null) { + return null; + } else if (this.args instanceof Map) { + return (this.args as Map).get(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args[key] + } else { + throw new Error("ClassCastException"); + } + } + + hasArgument(key: string): boolean { + if (arguments == null) { + return false; + } else if (arguments instanceof Map) { + return (this.args as Map).has(key); + } else if (ToolUtils.isObj(this.args)) { + return this.args.hasOwnProperty(key); + } else { + throw new Error("ClassCastException"); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets new file mode 100644 index 0000000000000000000000000000000000000000..e491ed5f7fec63ad1064c7e7ddbe468aaf3821df --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel.ets @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; +import MessageChannelUtils from '../../util/MessageChannelUtils'; +import { BinaryMessageHandler, BinaryMessenger, BinaryReply, TaskQueue } from './BinaryMessenger'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMethodCodec from './StandardMethodCodec'; +/** + * A named channel for communicating with the Flutter application using asynchronous method calls. + * + *

Incoming method calls are decoded from binary on receipt, and Java results are encoded into + * binary before being transmitted back to Flutter. The {@link MethodCodec} used must be compatible + * with the one used by the Flutter application. This can be achieved by creating a MethodChannel + * counterpart of this channel on the Dart side. The Java type of method call arguments and results + * is {@code Object}, but only values supported by the specified {@link MethodCodec} can be used. + * + *

The logical identity of the channel is given by its name. Identically named channels will + * interfere with each other's communication. + */ + +export default class MethodChannel { + static TAG = "MethodChannel#"; + private messenger: BinaryMessenger; + private name: string; + private codec: MethodCodec; + private taskQueue: TaskQueue; + + constructor(messenger: BinaryMessenger, name: string, codec: MethodCodec = StandardMethodCodec.INSTANCE, taskQueue?: TaskQueue) { + this.messenger = messenger + this.name = name + this.codec = codec + this.taskQueue = taskQueue + } + + /** + * Invokes a method on this channel, optionally expecting a result. + * + *

Any uncaught exception thrown by the result callback will be caught and logged. + * + * @param method the name String of the method. + * @param arguments the arguments for the invocation, possibly null. + * @param callback a {@link Result} callback for the invocation result, or null. + */ + invokeMethod(method: string, args: ESObject, callback?: MethodResult): void { + this.messenger.send(this.name, this.codec.encodeMethodCall(new MethodCall(method, args)), callback == null ? null : new IncomingResultHandler(callback, this.codec)); + } + + /** + * Registers a method call handler on this channel. + * + *

Overrides any existing handler registration for (the name of) this channel. + * + *

If no handler has been registered, any incoming method call on this channel will be handled + * silently by sending a null reply. This results in a MissingPluginException + * on the Dart side, unless an OptionalMethodChannel + * is used. + * + * @param handler a {@link MethodCallHandler}, or null to deregister. + */ + setMethodCallHandler(handler: MethodCallHandler): void { + // We call the 2 parameter variant specifically to avoid breaking changes in + // mock verify calls. + // See https://github.com/flutter/flutter/issues/92582. + if (this.taskQueue != null) { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec), this.taskQueue); + } else { + this.messenger.setMessageHandler( + this.name, handler == null ? null : new IncomingMethodCallHandler(handler, this.codec)); + } + } + + /** + * Adjusts the number of messages that will get buffered when sending messages to channels that + * aren't fully set up yet. For example, the engine isn't running yet or the channel's message + * handler isn't set up on the Dart side yet. + */ + resizeChannelBuffer(newSize: number): void { + MessageChannelUtils.resizeChannelBuffer(this.messenger, this.name, newSize); + } +} + +/** A handler of incoming method calls. */ +export interface MethodCallHandler { + /** + * Handles the specified method call received from Flutter. + * + *

Handler implementations must submit a result for all incoming calls, by making a single + * call on the given {@link Result} callback. Failure to do so will result in lingering Flutter + * result handlers. The result may be submitted asynchronously and on any thread. Calls to + * unknown or unimplemented methods should be handled using {@link Result#notImplemented()}. + * + *

Any uncaught exception thrown by this method will be caught by the channel implementation + * and logged, and an error result will be sent back to Flutter. + * + *

The handler is called on the platform thread (Android main thread) by default, or + * otherwise on the thread specified by the {@link BinaryMessenger.TaskQueue} provided to the + * associated {@link MethodChannel} when it was created. See also Threading in + * the Flutter Engine. + * + * @param call A {@link MethodCall}. + * @param result A {@link Result} used for submitting the result of the call. + */ + onMethodCall(call: MethodCall, result: MethodResult): void; +} + +/** + * Method call result callback. Supports dual use: Implementations of methods to be invoked by + * Flutter act as clients of this interface for sending results back to Flutter. Invokers of + * Flutter methods provide implementations of this interface for handling results received from + * Flutter. + * + *

All methods of this class can be invoked on any thread. + */ +export interface MethodResult { + /** + * Handles a successful result. + * + * @param result The result, possibly null. The result must be an Object type supported by the + * codec. For instance, if you are using {@link StandardMessageCodec} (default), please see + * its documentation on what types are supported. + */ + success: (result: ESObject) => void; + + /** + * Handles an error result. + * + * @param errorCode An error code String. + * @param errorMessage A human-readable error message String, possibly null. + * @param errorDetails Error details, possibly null. The details must be an Object type + * supported by the codec. For instance, if you are using {@link StandardMessageCodec} + * (default), please see its documentation on what types are supported. + */ + error: (errorCode: string, errorMessage: string, errorDetails: ESObject) => void; + + /** Handles a call to an unimplemented method. */ + notImplemented: () => void; +} + +class IncomingResultHandler implements BinaryReply { + private callback: MethodResult; + private codec: MethodCodec; + + constructor(callback: MethodResult, codec: MethodCodec) { + this.callback = callback; + this.codec = codec + } + + reply(reply: ArrayBuffer): void { + try { + if (reply == null) { + this.callback.notImplemented(); + } else { + try { + this.callback.success(this.codec.decodeEnvelope(reply)); + } catch (e) { + this.callback.error(e.code, e.getMessage(), e.details); + } + } + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call result", e); + } + } +} + +class IncomingMethodCallHandler implements BinaryMessageHandler { + private handler: MethodCallHandler; + private codec: MethodCodec; + + constructor(handler: MethodCallHandler, codec: MethodCodec) { + this.handler = handler; + this.codec = codec + } + + onMessage(message: ArrayBuffer, reply: BinaryReply): void { + const call = this.codec.decodeMethodCall(message); + try { + this.handler.onMethodCall( + call, { + success: (result: ESObject): void => { + reply.reply(this.codec.encodeSuccessEnvelope(result)); + }, + + error: (errorCode: string, errorMessage: string, errorDetails: ESObject): void => { + reply.reply(this.codec.encodeErrorEnvelope(errorCode, errorMessage, errorDetails)); + }, + + notImplemented: (): void => { + Log.w(MethodChannel.TAG,"method not implemented"); + reply.reply(null); + } + }); + } catch (e) { + Log.e(MethodChannel.TAG, "Failed to handle method call", e); + reply.reply(this.codec.encodeErrorEnvelopeWithStacktrace("error", e.getMessage(), null, e)); + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..86ed92aca6d512fa8247d963619acf67f29b7fe4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/MethodCodec.ets @@ -0,0 +1,87 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MethodCall from './MethodCall'; +/** + * A codec for method calls and enveloped results. + * + *

Method calls are encoded as binary messages with enough structure that the codec can extract a + * method name String and an arguments Object. These data items are used to populate a {@link + * MethodCall}. + * + *

All operations throw {@link IllegalArgumentException}, if conversion fails. + */ +export default interface MethodCodec { + /** + * Encodes a message call into binary. + * + * @param methodCall a {@link MethodCall}. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeMethodCall(methodCall: MethodCall): ArrayBuffer; + + /** + * Decodes a message call from binary. + * + * @param methodCall the binary encoding of the method call as a {@link ByteBuffer}. + * @return a {@link MethodCall} representation of the bytes between the given buffer's current + * position and its limit. + */ + decodeMethodCall(methodCall: ArrayBuffer): MethodCall; + + /** + * Encodes a successful result into a binary envelope message. + * + * @param result The result value, possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeSuccessEnvelope(result: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer; + + /** + * Encodes an error result into a binary envelope message with the native stacktrace. + * + * @param errorCode An error code String. + * @param errorMessage An error message String, possibly null. + * @param errorDetails Error details, possibly null. Consider supporting {@link Throwable} in your + * codec. This is the most common value passed to this field. + * @param errorStacktrace Platform stacktrace for the error. possibly null. + * @return a {@link ByteBuffer} containing the encoding between position 0 and the current + * position. + */ + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer + + /** + * Decodes a result envelope from binary. + * + * @param envelope the binary encoding of a result envelope as a {@link ByteBuffer}. + * @return the enveloped result Object. + * @throws FlutterException if the envelope was an error envelope. + */ + decodeEnvelope(envelope: ArrayBuffer): ESObject +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..cb92c8eb1acc0406e2f14229e8d29d0ef19b3030 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/PluginRegistry.ets @@ -0,0 +1,14 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..3de7603e1f576a9af23be11b9f185c67730429b3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec.ets @@ -0,0 +1,310 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * MessageCodec using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMessageCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Supported messages are acyclic values of these forms: + * + *

    + *
  • null + *
  • Booleans + *
  • number + *
  • BigIntegers (see below) + *
  • Int8Array, Int32Array, Float32Array, Float64Array + *
  • Strings + *
  • Array[] + *
  • Lists of supported values + *
  • Maps with supported keys and values + *
+ * + *

On the Dart side, these values are represented as follows: + * + *

    + *
  • null: null + *
  • Boolean: bool + *
  • Byte, Short, Integer, Long: int + *
  • Float, Double: double + *
  • String: String + *
  • byte[]: Uint8List + *
  • int[]: Int32List + *
  • long[]: Int64List + *
  • float[]: Float32List + *
  • double[]: Float64List + *
  • List: List + *
  • Map: Map + *
+ * + *

BigIntegers are represented in Dart as strings with the hexadecimal representation of the + * integer's value. + * + *

To extend the codec, overwrite the writeValue and readValueOfType methods. + */ +export default class StandardMessageCodec implements MessageCodec { + private static TAG = "StandardMessageCodec#"; + static INSTANCE = new StandardMessageCodec(); + + encodeMessage(message: ESObject): ArrayBuffer { + if (message == null) { + return null; + } + const stream = ByteBuffer.from(new ArrayBuffer(1024)) + this.writeValue(stream, message); + return stream.buffer + } + + decodeMessage(message: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(message) + return this.readValue(buffer) + } + + private static NULL = 0; + private static TRUE = 1; + private static FALSE = 2; + private static INT32 = 3; + private static INT64 = 4; + private static BIGINT = 5; + private static FLOAT64 = 6; + private static STRING = 7; + private static UINT8_ARRAY = 8; + private static INT32_ARRAY = 9; + private static INT64_ARRAY = 10; + private static FLOAT64_ARRAY = 11; + private static LIST = 12; + private static MAP = 13; + private static FLOAT32_ARRAY = 14; + + + writeValue(stream: ByteBuffer, value: ESObject): ESObject { + if (value == null || value == undefined) { + stream.writeInt8(StandardMessageCodec.NULL) + } else if (typeof value === "boolean") { + stream.writeInt8(value ? StandardMessageCodec.TRUE : StandardMessageCodec.FALSE) + } else if (typeof value === "number") { + if (Number.isInteger(value)) { //整型 + if (-0x7fffffff - 1 <= value && value <= 0x7fffffff) { + stream.writeInt8(StandardMessageCodec.INT32) + stream.writeInt32(value, true) + } else { + stream.writeInt8(StandardMessageCodec.INT64) + stream.writeInt64(value, true) + } + } else { //浮点型 + stream.writeInt8(StandardMessageCodec.FLOAT64) + this.writeAlignment(stream, 8); + stream.writeFloat64(value, true) + } + } else if (typeof value === "string") { + stream.writeInt8(StandardMessageCodec.STRING) + let stringBuff = StringUtils.stringToArrayBuffer(value) + this.writeBytes(stream, new Uint8Array(stringBuff)) + } else if (value instanceof Uint8Array) { + stream.writeInt8(StandardMessageCodec.UINT8_ARRAY) + this.writeBytes(stream, value) + } else if (value instanceof Int32Array) { + stream.writeInt8(StandardMessageCodec.INT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeInt32(item, true)) + } else if (value instanceof Float32Array) { + stream.writeInt8(StandardMessageCodec.FLOAT32_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 4); + value.forEach(item => stream.writeFloat32(item, true)) + } else if (value instanceof Float64Array) { + stream.writeInt8(StandardMessageCodec.FLOAT64_ARRAY) + this.writeSize(stream, value.length); + this.writeAlignment(stream, 8); + value.forEach(item => stream.writeFloat64(item, true)) + } else if (value instanceof Array) { + stream.writeInt8(StandardMessageCodec.LIST) + this.writeSize(stream, value.length); + value.forEach((item: ESObject): void => this.writeValue(stream, item)) + } else if (value instanceof Map) { + stream.writeInt8(StandardMessageCodec.MAP) + this.writeSize(stream, value.size); + value.forEach((value: ESObject, key: ESObject) => { + this.writeValue(stream, key); + this.writeValue(stream, value); + }) + } else if (typeof value == 'object') { + this.writeValue(stream, new Map(value.entries())) + } + return stream + } + + writeAlignment(stream: ByteBuffer, alignment: number) { + let mod: number = stream.byteOffset % alignment; + if (mod != 0) { + for (let i = 0; i < alignment - mod; i++) { + stream.writeInt8(0); + } + } + } + + writeSize(stream: ByteBuffer, value: number) { + if (value < 254) { + stream.writeInt8(value); + } else if (value <= 0xffff) { + stream.writeInt8(254); + stream.writeInt16(value, true); + } else { + stream.writeInt8(255); + stream.writeInt32(value, true); + } + } + + writeBytes(stream: ByteBuffer, bytes: Uint8Array) { + this.writeSize(stream, bytes.length) + bytes.forEach(item => stream.writeInt8(item)) + } + + readSize(buffer: ByteBuffer) { + let value = buffer.readInt8() & 0xff; + if (value < 254) { + return value; + } else if (value == 254) { + return buffer.readInt16(true); + } else { + return buffer.readInt32(true); + } + } + + readAlignment(buffer: ByteBuffer, alignment: number) { + let mod = buffer.byteOffset % alignment; + if (mod != 0) { + buffer.skip(alignment - mod); + } + } + + readValue(buffer: ByteBuffer): ESObject { + let type = buffer.readInt8() + return this.readValueOfType(type, buffer); + } + + readBytes(buffer: ByteBuffer): Uint8Array { + let length = this.readSize(buffer); + let bytes = new Uint8Array(length) + for (let i = 0; i < length; i++) { + bytes[i] = buffer.readUint8() + } + return bytes; + } + + readValueOfType(type: number, buffer: ByteBuffer): ESObject { + let result: ESObject; + switch (type) { + case StandardMessageCodec.NULL: + result = null; + break; + case StandardMessageCodec.TRUE: + result = true; + break; + case StandardMessageCodec.FALSE: + result = false; + break; + case StandardMessageCodec.INT32: + result = buffer.readInt32(true); + break; + case StandardMessageCodec.INT64: + result = buffer.readInt64(true); + break; + case StandardMessageCodec.BIGINT: + result = buffer.readBigInt64(true) + case StandardMessageCodec.FLOAT64: + this.readAlignment(buffer, 8); + result = buffer.readFloat64(true) + break; + case StandardMessageCodec.STRING: { + let bytes = this.readBytes(buffer); + result = StringUtils.arrayBufferToString(bytes.buffer); + break; + } + case StandardMessageCodec.UINT8_ARRAY: { + result = this.readBytes(buffer); + break; + } + case StandardMessageCodec.INT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Int32Array(length) + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt32(true) + } + result = array; + break; + } + case StandardMessageCodec.INT64_ARRAY: { //这里是都城array 还是 bigint待定 + let length = this.readSize(buffer); + let array: Array = new Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readInt64(true) + } + result = array; + break; + } + case StandardMessageCodec.FLOAT64_ARRAY: { + let length = this.readSize(buffer); + let array = new Float64Array(length) + this.readAlignment(buffer, 8); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat64(true) + } + result = array; + break; + } + case StandardMessageCodec.LIST: { + let length = this.readSize(buffer); + let array: Array = new Array(length) + for (let i = 0; i < length; i++) { + array[i] = this.readValue(buffer) + } + result = array; + break; + } + case StandardMessageCodec.MAP: { + let size = this.readSize(buffer); + let map: Map = new Map() + for (let i = 0; i < size; i++) { + map.set(this.readValue(buffer), this.readValue(buffer)); + } + result = map; + break; + } + case StandardMessageCodec.FLOAT32_ARRAY: { + let length = this.readSize(buffer); + let array = new Float32Array(length); + this.readAlignment(buffer, 4); + for (let i = 0; i < length; i++) { + array[i] = buffer.readFloat32(true) + } + result = array; + break; + } + default: + throw new Error("Message corrupted"); + } + return result; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..d4417c54eb56d55355b73104ee8626a17836735f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec.ets @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { ByteBuffer } from '../../util/ByteBuffer'; +import FlutterException from './FlutterException'; +import MethodCall from './MethodCall'; +import MethodCodec from './MethodCodec'; +import StandardMessageCodec from './StandardMessageCodec'; + +/** + * A {@link MethodCodec} using the Flutter standard binary encoding. + * + *

This codec is guaranteed to be compatible with the corresponding StandardMethodCodec + * on the Dart side. These parts of the Flutter SDK are evolved synchronously. + * + *

Values supported as method arguments and result payloads are those supported by {@link + * StandardMessageCodec}. + */ +export default class StandardMethodCodec implements MethodCodec { + private static TAG = "StandardMethodCodec"; + public static INSTANCE = new StandardMethodCodec(StandardMessageCodec.INSTANCE); + + private messageCodec: StandardMessageCodec; + + /** Creates a new method codec based on the specified message codec. */ + constructor(messageCodec: StandardMessageCodec) { + this.messageCodec = messageCodec; + } + + encodeMethodCall(methodCall: MethodCall): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + this.messageCodec.writeValue(stream, methodCall.method); + this.messageCodec.writeValue(stream, methodCall.args); + return stream.buffer; + } + + decodeMethodCall(methodCall: ArrayBuffer): MethodCall { + const buffer = ByteBuffer.from(methodCall); + const method: ESObject = this.messageCodec.readValue(buffer); + const args: ESObject = this.messageCodec.readValue(buffer); + if (typeof method == 'string' && !buffer.hasRemaining()) { + return new MethodCall(method, args); + } + throw new Error("Method call corrupted"); + } + + encodeSuccessEnvelope(result: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(0); + this.messageCodec.writeValue(stream, result); + return stream.buffer; + } + + encodeErrorEnvelope(errorCode: string, errorMessage: string, errorDetails: ESObject): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + return stream.buffer; + } + + encodeErrorEnvelopeWithStacktrace(errorCode: string, errorMessage: string, errorDetails: ESObject, errorStacktrace: string): ArrayBuffer { + const stream = ByteBuffer.from(new ArrayBuffer(1024)); + stream.writeInt8(1); + this.messageCodec.writeValue(stream, errorCode); + this.messageCodec.writeValue(stream, errorMessage); + if (errorDetails instanceof Error) { + this.messageCodec.writeValue(stream, errorDetails.stack); + } else { + this.messageCodec.writeValue(stream, errorDetails); + } + this.messageCodec.writeValue(stream, errorStacktrace); + return stream.buffer; + } + + decodeEnvelope(envelope: ArrayBuffer): ESObject { + const buffer = ByteBuffer.from(envelope); + const flag = buffer.readInt8(); + switch (flag) { + case 0: { + const result: ESObject = this.messageCodec.readValue(buffer); + if (!buffer.hasRemaining()) { + return result; + } + // Falls through intentionally. + } + case 1: { + const code: ESObject = this.messageCodec.readValue(buffer); + const message: ESObject = this.messageCodec.readValue(buffer); + const details: ESObject = this.messageCodec.readValue(buffer); + if (typeof code == 'string' && (message == null || typeof message == 'string') && !buffer.hasRemaining()) { + throw new FlutterException(code, message, details); + } + } + } + throw new Error("Envelope corrupted"); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets new file mode 100644 index 0000000000000000000000000000000000000000..e43be76b5527f6180d9b30ede5c1c07dff84c729 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/common/StringCodec.ets @@ -0,0 +1,42 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import StringUtils from '../../util/StringUtils'; +import MessageCodec from './MessageCodec'; + +/** + * A {@link MessageCodec} using UTF-8 encoded String messages. + * + *

This codec is guaranteed to be compatible with the corresponding StringCodec on the + * Dart side. These parts of the Flutter SDK are evolved synchronously. + */ +export default class StringCodec implements MessageCodec { + static readonly INSTANCE = new StringCodec(); + + encodeMessage(message: string): ArrayBuffer { + if (message == null) { + return null; + } + return StringUtils.stringToArrayBuffer(message); + } + + decodeMessage(message: ArrayBuffer): string { + if (message == null) { + return null; + } + return StringUtils.arrayBufferToString(message); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets new file mode 100644 index 0000000000000000000000000000000000000000..72735c0a29a1e893e8bf986458cea0da82df0d2b --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/ListenableEditingState.ets @@ -0,0 +1,265 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { TextEditState } from '../../embedding/engine/systemchannels/TextInputChannel'; +import Log from '../../util/Log'; +import inputMethod from '@ohos.inputMethod'; +import ArrayList from '@ohos.util.ArrayList'; +import { TextEditingDelta } from './TextEditingDelta'; + +const TAG = "ListenableEditingState"; +export class ListenableEditingState { + //Cache used to storage software keyboard input action + private mStringCache: string; + private mSelectionStartCache: number; + private mSelectionEndCache: number; + private mComposingStartCache: number; + private mComposingEndCache: number; + //used to compare with Cache + private mTextInputState: TextEditState; + private mListeners: ArrayList = new ArrayList(); + private mPendingListeners: ArrayList = new ArrayList(); + private mBatchTextEditingDeltas: ArrayList = new ArrayList(); + private mChangeNotificationDepth: number; + private mBatchEditNestDepth: number; + + private mTextWhenBeginBatchEdit: string; + private mSelectionStartWhenBeginBatchEdit: number; + private mSelectionEndWhenBeginBatchEdit: number; + private mComposingStartWhenBeginBatchEdit: number; + private mComposingEndWhenBeginBatchEdit: number; + + + constructor() { + this.mStringCache = ""; + this.mSelectionStartCache = 0; + this.mSelectionEndCache = 0; + this.mComposingStartCache = -1; + this.mComposingEndCache = -1; + } + + + getSelectionStart(): number { + return this.mSelectionStartCache; + } + + getSelectionEnd(): number { + return this.mSelectionEndCache; + } + + getComposingStart(): number { + return this.mComposingStartCache; + } + + getComposingEnd(): number { + return this.mComposingEndCache; + } + + getStringCache(): string { + return this.mStringCache; + } + + setSelectionStart(newSelectionStart: number): void { + this.mSelectionStartCache = newSelectionStart; + } + + setSelectionEnd(newSelectionEnd: number): void { + this.mSelectionEndCache = newSelectionEnd; + } + + setComposingStart(newComposingStart: number): void { + this.mComposingStartCache = newComposingStart; + } + + setComposingEnd(newComposingEnd: number): void { + this.mComposingEndCache = newComposingEnd; + } + + setStringCache(newStringCache: string): void { + this.mStringCache = newStringCache; + } + + notifyListener(listener: EditingStateWatcher, + textChanged: boolean, + selectionChanged: boolean, + composingChanged: boolean): void { + this.mChangeNotificationDepth++; + listener.didChangeEditingState(textChanged, selectionChanged, composingChanged); + this.mChangeNotificationDepth--; + } + + notifyListenersIfNeeded(textChanged: boolean, selectionChanged: boolean, composingChanged: boolean) { + if (textChanged || selectionChanged || composingChanged) { + for(const listener of this.mListeners) { + this.notifyListener(listener, textChanged, selectionChanged, composingChanged); + } + + } + } + + handleInsertTextEvent(text: string): void { + if(this.mTextInputState == null) { + Log.e(TAG, "mTextInputState is null"); + } + if(this.mStringCache.length == this.mSelectionStartCache) { + //Insert text one by one + this.mStringCache += text; + this.setSelectionStart(this.mStringCache.length); + this.setSelectionEnd(this.mStringCache.length); + + } else if(this.mStringCache.length > this.mSelectionStartCache) { + //Insert text in the middle of string + let tempStr: string = this.mStringCache.substring(0, this.mSelectionStartCache) + text + this.mStringCache.substring(this.mSelectionStartCache); + this.mStringCache = tempStr; + this.mSelectionStartCache += text.length; + this.mSelectionEndCache = this.mSelectionStartCache; + } + if(this.mListeners == null) { + Log.e(TAG, "mListeners is null"); + return; + } + this.notifyListenersIfNeeded(true, true, false); + } + + updateTextInputState(state: TextEditState): void { + this.beginBatchEdit(); + this.setStringCache(state.text); + if(state.hasSelection()) { + this.setSelectionStart(state.selectionStart); + this.setSelectionEnd(state.selectionEnd); + } else { + this.setSelectionStart(0); + this.setSelectionEnd(0); + } + this.endBatchEdit(); + } + + beginBatchEdit(): void { + this.mBatchEditNestDepth++; + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "editing state should not be changed in a listener callback"); + } + if(this.mBatchEditNestDepth == 1 && !this.mListeners.isEmpty()) { + this.mTextWhenBeginBatchEdit = this.getStringCache(); + this.mSelectionStartWhenBeginBatchEdit = this.getSelectionStart(); + this.mSelectionEndWhenBeginBatchEdit = this.getSelectionEnd(); + this.mComposingStartWhenBeginBatchEdit = this.getComposingStart(); + this.mComposingEndWhenBeginBatchEdit = this.getComposingEnd(); + } + } + + endBatchEdit(): void { + if (this.mBatchEditNestDepth == 0) { + Log.e(TAG, "endBatchEdit called without a matching beginBatchEdit"); + return; + } + if(this.mBatchEditNestDepth == 1) { + Log.d(TAG,"mBatchEditNestDepth == 1"); + for(const listener of this.mPendingListeners) { + this.notifyListener(listener, true, true, true); + } + + if(!this.mListeners.isEmpty()) { + Log.d(TAG, "didFinishBatchEdit with " + this.mListeners.length + " listener(s)"); + const textChanged = !(this.mStringCache == this.mTextWhenBeginBatchEdit); + const selectionChanged = this.mSelectionStartWhenBeginBatchEdit != this.getSelectionStart() + || this.mSelectionEndWhenBeginBatchEdit != this.getSelectionEnd(); + const composingRegionChanged = this.mComposingStartWhenBeginBatchEdit != this.getComposingStart() + || this.mComposingEndWhenBeginBatchEdit != this.getComposingEnd(); + Log.d(TAG,"textChanged: " + textChanged + " selectionChanged: " + selectionChanged + + " composingRegionChanged: " + composingRegionChanged); + this.notifyListenersIfNeeded(textChanged, selectionChanged, composingRegionChanged); + } + } + for(const listener of this.mPendingListeners) { + this.mListeners.add(listener); + } + this.mPendingListeners.clear(); + this.mBatchEditNestDepth--; + + } + + addEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "adding a listener " + JSON.stringify(listener) + " in a listener callback"); + } + if(this.mBatchEditNestDepth > 0) { + Log.d(TAG, "a listener was added to EditingState while a batch edit was in progress"); + this.mPendingListeners.add(listener); + } else { + this.mListeners.add(listener); + } + } + + removeEditingStateListener(listener: EditingStateWatcher): void { + if(this.mChangeNotificationDepth > 0) { + Log.e(TAG, "removing a listener " + JSON.stringify(listener) + " in a listener callback"); + } + this.mListeners.remove(listener); + if(this.mBatchEditNestDepth > 0) { + this.mPendingListeners.remove(listener); + } + } + + handleDeleteEvent(leftOrRight: boolean, length: number): void { + if(leftOrRight == false) { + //delete left + if(this.mSelectionStartCache == 0) { + return; + } + this.mSelectionStartCache -= length; + let tempStr: string = this.mStringCache.slice(0, this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionStartCache + length); + this.mStringCache = tempStr; + this.mSelectionEndCache = this.mSelectionStartCache; + } else if(leftOrRight == true) { + //delete right + if(this.mSelectionStartCache == this.mStringCache.length) { + return; + } + this.mSelectionEndCache += length; + let tempStr: string = this.mStringCache.slice(0,this.mSelectionStartCache) + this.mStringCache.slice(this.mSelectionEndCache); + this.mStringCache = tempStr; + this.mSelectionStartCache = this.mSelectionEndCache; + } + this.notifyListenersIfNeeded(true, true, false); + } + + handleFunctionKey(functionKey: inputMethod.FunctionKey): void { + switch (functionKey.enterKeyType) { + case inputMethod.EnterKeyType.PREVIOUS: + case inputMethod.EnterKeyType.UNSPECIFIED: + case inputMethod.EnterKeyType.NONE: + case inputMethod.EnterKeyType.GO: + case inputMethod.EnterKeyType.SEARCH: + case inputMethod.EnterKeyType.SEND: + case inputMethod.EnterKeyType.NEXT: + case inputMethod.EnterKeyType.DONE: + + } + } + + handleSelectByRange(range: inputMethod.Range): void { + Log.d(TAG, "handleSelectByRange start: " + range.start +" end: " + range.end); + } + + + +} + +export interface EditingStateWatcher { + // Changing the editing state in a didChangeEditingState callback may cause unexpected + // behavior. + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets new file mode 100644 index 0000000000000000000000000000000000000000..c61296f6dae8b30fcb035f72d8457ca36d83a015 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextEditingDelta.ets @@ -0,0 +1,61 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '../../util/Log'; + +export class TextEditingDelta { + private static TAG = "TextEditingDelta"; + private oldText: string; + private deltaText: string; + private deltaStart: number; + private deltaEnd: number; + private newSelectionStart: number; + private newSelectionEnd: number; + private newComposingStart: number; + private newComposingEnd: number; + + constructor(oldEditable: string, + selectionStart: number, + selectionEnd: number, + composingStart: number, + composingEnd: number, + replacementDestinationStart?: number, + replacementDestinationEnd?: number, + replacementSource?: string,) { + this.newSelectionStart = selectionStart; + this.newSelectionEnd = selectionEnd; + this.newComposingStart = composingStart; + this.newComposingEnd = composingEnd; + if(replacementDestinationStart === undefined || + replacementDestinationEnd === undefined || + replacementSource === undefined) { + this.setDeltas(oldEditable, "", -1, -1); + } else { + this.setDeltas( + oldEditable, + replacementSource, + replacementDestinationStart, + replacementDestinationEnd); + } + + } + + setDeltas(oldText: string, newText: string, newStart: number, newExtent: number): void { + this.oldText = oldText; + this.deltaText = newText; + this.deltaStart = newStart; + this.deltaEnd = newExtent; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..6df66b9cfde51d0d47c80b693b28f1f049c38b09 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/editing/TextInputPlugin.ets @@ -0,0 +1,262 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import TextInputChannel, { Configuration, TextEditState, + TextInputMethodHandler, + TextInputType } from '../../embedding/engine/systemchannels/TextInputChannel'; +import inputMethod from '@ohos.inputMethod'; +import Log from '../../util/Log'; +import { EditingStateWatcher, ListenableEditingState } from './ListenableEditingState'; + +export default class TextInputPlugin implements EditingStateWatcher{ + private static TAG = "TextInputPlugin"; + private textInputChannel: TextInputChannel; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private mEditable: ListenableEditingState; + + constructor(textInputChannel: TextInputChannel) { + this.textInputChannel = textInputChannel; + this.mEditable = new ListenableEditingState(); + this.inputMethodController = inputMethod.getController(); + let textInputMethodHandler = new TextInputMethodHandlerImpl(this); + this.textInputChannel.setTextInputMethodHandler(textInputMethodHandler); + } + + public clearTextInputClient() { + this.textInputChannel.textInputMethodHandler.clearClient(); + } + setTextInputEditingState(state: TextEditState) { + + } + + didChangeEditingState(textChanged: boolean, selectionChanged: boolean, composingRegionChanged: boolean): void { + this.textInputChannel.updateEditingState(this.inputTarget.id, this.mEditable.getStringCache(), + this.mEditable.getSelectionStart(), this.mEditable.getSelectionEnd(), + this.mEditable.getComposingStart(), this.mEditable.getComposingEnd()) + } + + detach(): void { + this.inputMethodController.detach((err) => { + if(err) { + Log.e(TextInputPlugin.TAG, "Failed to detach: " + JSON.stringify(err)); + } + }) + } + +} + +class TextInputMethodHandlerImpl implements TextInputMethodHandler { + private static TAG = "TextInputMethodHandlerImpl"; + private textConfig: inputMethod.TextConfig; + private inputMethodController: inputMethod.InputMethodController; + private inputTarget: InputTarget; + private configuration: Configuration; + private mEditable: ListenableEditingState; + private mRestartInputPending: boolean; + private plugin: EditingStateWatcher; + + private imcFlag: boolean = false; + + constructor(plugin: EditingStateWatcher) { + this.textConfig = { + inputAttribute: { + textInputType: 0, + enterKeyType: 1 + }}; + this.plugin = plugin; + } + + show(): void { + this.showTextInput(); + } + + hide(): void { + this.hideTextInput(); + } + + requestAutofill(): void { + + } + + finishAutofillContext(shouldSave: boolean): void { + + } + + setClient(textInputClientId: number, configuration: Configuration): void { + Log.d(TextInputMethodHandlerImpl.TAG,"textInputClientId: " + textInputClientId); + this.setTextInputClient(textInputClientId, configuration); + } + + setPlatformViewClient(id: number, usesVirtualDisplay: boolean): void { + + } + + setEditableSizeAndTransform(width: number, height: number, transform: number[]): void { + + } + + setEditingState(editingState: TextEditState): void { + Log.d(TextInputMethodHandlerImpl.TAG, "text:" + editingState.text +" selectionStart:" + editingState.selectionStart + " selectionEnd:" + + editingState.selectionEnd + " composingStart:" + editingState.composingStart + " composingEnd" + editingState.composingEnd); + this.mEditable.updateTextInputState(editingState); + } + + clearClient(): void { + this.clearTextInputClient(); + } + + private async showTextInput(): Promise { + await this.attach(true); + if(this.imcFlag != true) { + this.listenKeyBoardEvent(); + } + this.inputMethodController.showTextInput().then(()=> { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in showing softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to show softKeyboard:" + JSON.stringify(err)); + }); + } + + private async hideTextInput(): Promise { + this.inputMethodController.hideTextInput().then(() => { + Log.d(TextInputMethodHandlerImpl.TAG, "Succeeded in hide softKeyboard"); + }).catch((err: ESObject) => { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to hide softKeyboard:" + JSON.stringify(err)); + }) + } + + async attach(showKeyboard: boolean): Promise { + try { + await this.inputMethodController.attach(showKeyboard, this.textConfig); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to attach:" + JSON.stringify(err)); + } + } + + setTextInputClient(client: number, configuration: Configuration): void { + this.configuration = configuration; + if(this.canShowTextInput()) { + this.inputTarget = new InputTarget(Type.FRAMEWORK_CLIENT, client); + } else { + this.inputTarget = new InputTarget(Type.NO_TARGET, client); + } + this.mEditable.removeEditingStateListener(this.plugin); + this.mEditable = new ListenableEditingState(); + + this.mRestartInputPending = true; + this.mEditable.addEditingStateListener(this.plugin); + } + + canShowTextInput(): boolean { + if(this.configuration == null || this.configuration.inputType == null) { + return true; + } + return this.configuration.inputType.type != TextInputType.NONE; + } + + listenKeyBoardEvent(): void { + try { + this.inputMethodController.on('insertText', (text) => { + Log.d(TextInputMethodHandlerImpl.TAG, "insertText: " + text); + this.mEditable.handleInsertTextEvent(text); + }); + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe insertText:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteLeft', (length) => { + this.mEditable.handleDeleteEvent(false, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteLeft:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('deleteRight', (length) => { + this.mEditable.handleDeleteEvent(true, length); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe deleteRight:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('sendFunctionKey', (functionKey) => { + this.mEditable.handleFunctionKey(functionKey); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe sendFunctionKey:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + + try { + this.inputMethodController.on('selectByRange', (range: inputMethod.Range) => { + this.mEditable.handleSelectByRange(range); + }) + } catch (err) { + Log.e(TextInputMethodHandlerImpl.TAG, "Failed to subscribe selectByRange:" + JSON.stringify(err)); + this.cancelListenKeyBoardEvent(); + return; + } + Log.d(TextInputMethodHandlerImpl.TAG, "listenKeyBoardEvent success"); + this.imcFlag = true; + } + + cancelListenKeyBoardEvent(): void { + this.inputMethodController.off('insertText'); + this.inputMethodController.off('deleteLeft'); + this.inputMethodController.off('deleteRight'); + this.inputMethodController.off('sendFunctionKey'); + this.inputMethodController.off('selectByRange'); + } + + public clearTextInputClient(): void { + if(this.inputTarget.type == Type.VIRTUAL_DISPLAY_PLATFORM_VIEW) { + return; + } + this.mEditable.removeEditingStateListener(this.plugin); + this.configuration = null; + this.inputTarget = new InputTarget(Type.NO_TARGET, 0); + } +} + +enum Type { + NO_TARGET, + // InputConnection is managed by the TextInputPlugin, and events are forwarded to the Flutter + // framework. + FRAMEWORK_CLIENT, + // InputConnection is managed by a platform view that is presented on a virtual display. + VIRTUAL_DISPLAY_PLATFORM_VIEW, + PHYSICAL_DISPLAY_PLATFORM_VIEW, +} + +export class InputTarget { + type: Type; + id: number; + + constructor(type: Type, id: number) { + this.type = type; + this.id = id; + } + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..78ed1c729717344a6e387d3d3dbe62fb4e4df86c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/localization/LocalizationPlugin.ets @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import LocalizationChannel, { LocalizationMessageHandler } from '../../embedding/engine/systemchannels/LocalizationChannel' +import common from '@ohos.app.ability.common'; +import intl from '@ohos.intl'; +import Log from '../../util/Log'; +import i18n from '@ohos.i18n'; + +const TAG = "LocalizationPlugin"; +export default class LocalizationPlugin { + private localizationChannel:LocalizationChannel; + private context: common.Context; + + localeFromString(localeString: string): intl.Locale { + localeString = localeString.replace('_','-'); + let parts: string[] = localeString.split('-',-1); + let languageCode = parts[0]; + let scriptCode = ""; + let countryCode = ""; + let index: number = 1; + + if (parts.length > index && parts[index].length == 4) { + scriptCode = parts[index]; + index++; + } + + if (parts.length > index && parts[index].length >= 2 && parts[index].length <= 3) { + countryCode = parts[index]; + index++; + } + return new intl.Locale(languageCode+'-'+ countryCode +'-' + scriptCode); + } + + private localizationMessageHandler: LocalizationMessageHandler =new enterGetStringResource(()=>{ + Log.i(TAG, "getResource enter"); + return "" + }) + constructor(context: common.Context, localizationChannel: LocalizationChannel) { + this.context = context; + this.localizationChannel = localizationChannel; + this.localizationChannel.setLocalizationMessageHandler(this.localizationMessageHandler); + } + + sendLocaleToFlutter(): void { + let systemLanguages = i18n.System.getSystemLanguages(); + this.localizationChannel.sendLocales(systemLanguages); + } +} +class enterGetStringResource{ + getStringResource : (key: string, localeString: string)=>string + + constructor(getStringResource: (key: string, localeString: string)=>string) { + this.getStringResource = getStringResource + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..44c94a11aa2f132f6dd24b3484bb5ca9b59c940c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/mouse/MouseCursorPlugin.ets @@ -0,0 +1,129 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MouseCursorChannel, { MouseCursorMethodHandler } from '../../embedding/engine/systemchannels/MouseCursorChannel'; +import pointer from '@ohos.multimodalInput.pointer'; +import HashMap from '@ohos.util.HashMap'; +import Log from '../../util/Log'; +import { AsyncCallback } from '@ohos.base'; + +const TAG: string = "MouseCursorPlugin"; +export default class MouseCursorPlugin implements MouseCursorMethodHandler{ + private mView: MouseCursorViewDelegate; + + private mouseCursorChannel: MouseCursorChannel; + + private systemCursorConstants: HashMap; + + constructor(mouseCursorView: MouseCursorViewDelegate, mouseCursorChannel: MouseCursorChannel) { + this.mView = mouseCursorView; + this.mouseCursorChannel = mouseCursorChannel; + this.mouseCursorChannel.setMethodHandler(this); + } + + activateSystemCursor(kind: string): void { + this.mView.getWindowId((error, windowId) => { + if (windowId < 0) { + Log.w(TAG, "set point style failed windowId is invalid"); + return; + } + let pointStyle: pointer.PointerStyle = this.resolveSystemCursor(kind); + try { + pointer.setPointerStyle(windowId, pointStyle, (err: ESObject) => { + Log.i(TAG, "set point style success kind : " + kind); + }) + } catch (e) { + Log.e(TAG, "set point style failed : " + kind + " " + JSON.stringify(e)); + } + }); + } + + /** + * Return mouse cursor point style + * + *

This method guarantees to return a non-null object. + * + * @param kind mouse cursor type + * @returns point style + */ + private resolveSystemCursor(kind: string): pointer.PointerStyle { + if (this.systemCursorConstants == null) { + this.systemCursorConstants = new HashMap(); + this.systemCursorConstants.set("alias", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("allScroll", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("basic", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("cell", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("click", pointer.PointerStyle.HAND_POINTING); + this.systemCursorConstants.set("contextMenu", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("copy", pointer.PointerStyle.CURSOR_COPY); + this.systemCursorConstants.set("forbidden", pointer.PointerStyle.CURSOR_FORBID); + this.systemCursorConstants.set("grab", pointer.PointerStyle.HAND_OPEN); + this.systemCursorConstants.set("grabbing", pointer.PointerStyle.HAND_GRABBING); + this.systemCursorConstants.set("help", pointer.PointerStyle.HELP); + this.systemCursorConstants.set("move", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("none", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("noDrop", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("precise", pointer.PointerStyle.CROSS); + this.systemCursorConstants.set("text", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("resizeColum", pointer.PointerStyle.NORTH_SOUTH); + this.systemCursorConstants.set("resizeDown", pointer.PointerStyle.SOUTH); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeDownRight", pointer.PointerStyle.SOUTH_EAST); + this.systemCursorConstants.set("resizeLeft", pointer.PointerStyle.WEST); + this.systemCursorConstants.set("resizeLeftRight", pointer.PointerStyle.RESIZE_LEFT_RIGHT); + this.systemCursorConstants.set("resizeRight", pointer.PointerStyle.EAST); + this.systemCursorConstants.set("resizeRow", pointer.PointerStyle.WEST_EAST); + this.systemCursorConstants.set("resizeUp", pointer.PointerStyle.NORTH); + this.systemCursorConstants.set("resizeUpDown", pointer.PointerStyle.RESIZE_UP_DOWN); + this.systemCursorConstants.set("resizeUpLeft", pointer.PointerStyle.NORTH_WEST); + this.systemCursorConstants.set("resizeUpRight", pointer.PointerStyle.NORTH_EAST); + this.systemCursorConstants.set("resizeUpLeftDownRight", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("resizeUpRightDownLeft", pointer.PointerStyle.MOVE); + this.systemCursorConstants.set("verticalText", pointer.PointerStyle.TEXT_CURSOR); + this.systemCursorConstants.set("wait", pointer.PointerStyle.DEFAULT); + this.systemCursorConstants.set("zoomIn", pointer.PointerStyle.ZOOM_IN); + this.systemCursorConstants.set("zoomOut", pointer.PointerStyle.ZOOM_OUT); + } + let pointStyle:pointer.PointerStyle = this.systemCursorConstants.get(kind); + if (pointStyle === null) { + return pointer.PointerStyle.DEFAULT; + } + return pointStyle; + } + + /** + * Detaches the text input plugin from the platform views controller; + * + *

The MouseCursorPlugin instance should not be used after call this. + */ + destroy(): void { + this.mouseCursorChannel.setMethodHandler(null); + } +} + +/** + * Delegate interface for requesting the system to display a pointer icon object. + * + *

Typically implemented by an component, such as a{@code FlutterView} + */ +export interface MouseCursorViewDelegate { + /** + * get window id to set mouse style + *

component need to implement this interface to get windowId + * + * @param callback windowId + * */ + getWindowId(callback: AsyncCallback): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..faa3bc90e50c304744883689a532d0dc323bd714 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/AccessibilityEventsDelegate.ets @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export class AccessibilityEventsDelegate { + private accessibilityBridge: AccessibilityBridge; + + requestSendAccessibilityEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + onAccessibilityHoverEvent(accessibilityBridge: AccessibilityBridge): boolean { + if (accessibilityBridge == null) { + return false; + } + return true; + } + + setAccessibilityBridge (accessibilityBridge: AccessibilityBridge): void { + this.accessibilityBridge = accessibilityBridge; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets new file mode 100644 index 0000000000000000000000000000000000000000..64e8c7f780dc9253f3fd79c05663805a13c8d839 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformOverlayView.ets @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; + +export class PlatformOverlayView { + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + + constructor(context: Context, width: Number, height: Number, accessibilityEventsDelegate: AccessibilityEventsDelegate) { + this.accessibilityEventsDelegate= accessibilityEventsDelegate; + } + + public onHoverEvent(): boolean { + return false; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets new file mode 100644 index 0000000000000000000000000000000000000000..ddf5f59a71c4d1c7d51082bcf104990e0faa08c6 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView.ets @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DynamicView } from '../../view/DynamicView/dynamicView' + +/** A handle to an DynamicView to be embedded in the Flutter hierarchy. */ +export default abstract class PlatformView { + /** Returns the DynamicView to be embedded in the Flutter hierarchy. */ + abstract getView(): DVModel; + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is + * associated with the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} can now + * render a UI and interact with the user. + * + *

Some platform views may have unusual dependencies on the {@link View} that renders Flutter + * UIs, such as unique keyboard interactions. That {@link View} is provided here for those + * purposes. Use of this {@link View} should be avoided if it is not absolutely necessary, because + * depending on this {@link View} will tend to make platform view code more brittle to future + * changes. + */ + onFlutterViewAttached(dvModel: DVModel): void {} + + /** + * Called by the {@link io.flutter.embedding.engine.FlutterEngine} that owns this {@code + * PlatformView} when the DynamicView responsible for rendering a Flutter UI is detached + * and disassociated from the {@link io.flutter.embedding.engine.FlutterEngine}. + * + *

This means that our associated {@link io.flutter.embedding.engine.FlutterEngine} no longer + * has a rendering surface, or a user interaction surface of any kind. + * + *

This platform view must release any references related to the DynamicView that was + * provided in {@link #onFlutterViewAttached(View)}. + */ + onFlutterViewDetached(): void {} + + /** + * Dispose this platform view. + * + *

The {@link PlatformView} object is unusable after this method is called. + * + *

Plugins implementing {@link PlatformView} must clear all references to the View object and + * the PlatformView after this method is called. Failing to do so will result in a memory leak. + * + *

References related to the DynamicView attached in {@link + * #onFlutterViewAttached(View)} must be released in {@code dispose()} to avoid memory leaks. + */ + abstract dispose(): void; + + /** + * Callback fired when the platform's input connection is locked, or should be used. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionLocked(): void {} + + /** + * Callback fired when the platform input connection has been unlocked. + * + *

This hook only exists for rare cases where the plugin relies on the state of the input + * connection. This probably doesn't need to be implemented. + */ + onInputConnectionUnlocked(): void {} +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..373a7ea5a5906c812c330762fd3825d4ce420201 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewFactory.ets @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import MessageCodec from '../common/MessageCodec'; +import PlatformView from './PlatformView' +import common from '@ohos.app.ability.common'; + +export default abstract class PlatformViewFactory { + private createArgsCodec: MessageCodec; + + /** @param createArgsCodec the codec used to decode the args parameter of {@link #create}. */ + constructor(createArgsCodec: MessageCodec) { + this.createArgsCodec = createArgsCodec; + } + + /** + * Creates a new Dynamic be embedded in the Flutter hierarchy. + * + * @param context the context to be used when creating the view, this is different than + * FlutterView's context. + * @param viewId unique identifier for the created instance, this value is known on the Dart side. + * @param args arguments sent from the Flutter app. The bytes for this value are decoded using the + * createArgsCodec argument passed to the constructor. This is null if createArgsCodec was + * null, or no arguments were sent from the Flutter app. + */ + public abstract create(context: common.Context, viewId: number, args: ESObject): PlatformView; + + /** Returns the codec to be used for decoding the args parameter of {@link #create}. */ + getCreateArgsCodec(): MessageCodec { + return this.createArgsCodec; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..2c49f5eeaddb54cece120df8eea307c69ad76ebf --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistry.ets @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import PlatformViewFactory from './PlatformViewFactory' + +/** + * Registry for platform view factories. + * + *

Plugins can register factories for specific view types. + */ +export default interface PlatformViewRegistry { + /** + * Registers a factory for a platform view. + * + * @param viewTypeId unique identifier for the platform view's type. + * @param factory factory for creating platform views of the specified type. + * @return true if succeeded, false if a factory is already registered for viewTypeId. + */ + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets new file mode 100644 index 0000000000000000000000000000000000000000..98cb247d890cbe65150feb84242c01128047e7f9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewRegistryImpl.ets @@ -0,0 +1,40 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HashMap from '@ohos.util.HashMap'; +import PlatformViewFactory from './PlatformViewFactory' +import PlatformViewRegistry from './PlatformViewRegistry' + +export default class PlatformViewRegistryImpl implements PlatformViewRegistry { + // Maps a platform view type id to its factory. + private viewFactories: HashMap; + + constructor() { + this.viewFactories = new HashMap(); + } + + registerViewFactory(viewTypeId: string, factory: PlatformViewFactory): boolean { + if (this.viewFactories.hasKey(viewTypeId)) { + return false; + } + + this.viewFactories.set(viewTypeId, factory); + return true; + } + + getFactory(viewTypeId: string): PlatformViewFactory { + return this.viewFactories.get(viewTypeId); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets new file mode 100644 index 0000000000000000000000000000000000000000..c34d9bcce565e65f3eebb5cccf355a9d3f366fac --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewWrapper.ets @@ -0,0 +1,111 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor'; +import { DVModel, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; +import { RootDvModeManager } from './RootDvModelManager'; +import matrix4 from '@ohos.matrix4' +import Log from '../../util/Log'; + +const TAG: string = "PlatformViewWrapper"; +export class PlatformViewWrapper { + private prevLeft: number; + private prevTop: number; + private left: number; + private top: number; + private bufferWidth: number; + private bufferHeight: number; + private touchProcessor: OhosTouchProcessor; + + // private onTouch = (touchEvent: TouchEvent) => { + // switch (touchEvent.type) { + // case TouchType.Down: + // this.prevLeft = this.left; + // this.prevTop = this.top; + // this.model.params.translateX = this.left; + // this.model.params.translateY = this.top; + // break; + // case TouchType.Move: + // this.model.params.translateX = this.prevLeft; + // this.model.params.translateY = this.prevTop; + // this.prevLeft = this.left; + // this.prevTop = this.top; + // break; + // case TouchType.Up: + // case TouchType.Cancel: + // default: + // break; + // } + // } + + private model : DVModel = createDVModelFromJson( new DVModelParam("Column", [])); + + public setTouchProcessor(newTouchProcessor: OhosTouchProcessor): void { + this.touchProcessor = newTouchProcessor; + } + + constructor() { + } + + public getDvModel(): DVModel { + return this.model; + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + + public setLayoutParams(parameters : DVModelParameters): void { + if (this.model.params == null) { + this.model.params = new DVModelParameters(); + } + this.setParams(this.model.params, "marginLeft", this.getParams(parameters, "marginLeft")); + this.setParams(this.model.params, "marginTop", this.getParams(parameters, "marginTop")); + this.left = this.getParams(parameters, "marginLeft"); + this.top = this.getParams(parameters, "marginTop"); + + this.setParams(this.model.params, "width", this.getParams(parameters, "width")); + this.setParams(this.model.params, "height", this.getParams(parameters, "height")); + + // this.model.params.marginLeft = parameters.marginLeft; + // this.model.params.marginTop = parameters.marginTop; + // this.left = parameters.marginLeft; + // this.top = parameters.marginTop;; + + // this.model.params.width = parameters.width; + // this.model.params.height = parameters.height; + } + + public addDvModel(model: DVModel): void { + this.model.children.push(model); + } +} + +class DVModelParam { + compType: string + children: [] + + constructor(compType: string, children: []) { + this.compType = compType; + this.children = children; + } +}; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets new file mode 100644 index 0000000000000000000000000000000000000000..62888046c561533a3ea096c77ce7f3f634503e4c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsAccessibilityDelegate.ets @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import AccessibilityBridge from '../../view/AccessibilityBridge'; + +export interface PlatformViewsAccessibilityDelegate { + /** + * Returns the root of the view hierarchy for the platform view with the requested id, or null if + * there is no corresponding view. + */ + getPlatformViewById(viewId: number): Object; + + /** Returns true if the platform view uses virtual displays. */ + usesVirtualDisplay(id: number): boolean; + + /** + * Attaches an accessibility bridge for this platform views accessibility delegate. + * + *

Accessibility events originating in platform views belonging to this delegate will be + * delegated to this accessibility bridge. + */ + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void; + + /** + * Detaches the current accessibility bridge. + * + *

Any accessibility events sent by platform views belonging to this delegate will be ignored + * until a new accessibility bridge is attached. + */ + detachAccessibilityBridge(): void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets new file mode 100644 index 0000000000000000000000000000000000000000..b77917fc75a9baaf6c7f88a4df6fd4349a5b789c --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformViewsController.ets @@ -0,0 +1,502 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { PlatformViewsAccessibilityDelegate } from './PlatformViewsAccessibilityDelegate'; +import PlatformViewsChannel, { + PlatformViewBufferResized, + PlatformViewCreationRequest, + PlatformViewResizeRequest, + PlatformViewsHandler, PlatformViewTouch, PlatformViewBufferSize +} from '../../../ets/embedding/engine/systemchannels/PlatformViewsChannel'; +import PlatformView from './PlatformView'; +import { DVModel, DVModelParameters, DynamicView } from '../../view/DynamicView/dynamicView'; +import display from '@ohos.display'; +import { FlutterView } from '../../view/FlutterView'; +import { TextureRegistry } from '../../view/TextureRegistry'; +import TextInputPlugin from '../editing/TextInputPlugin'; +import { PlatformOverlayView } from './PlatformOverlayView'; +import { PlatformViewWrapper } from './PlatformViewWrapper'; +import { FlutterOverlaySurface } from '../../embedding/engine/FlutterOverlaySurface'; +import HashSet from '@ohos.util.HashSet'; +import PlatformViewRegistry from './PlatformViewRegistry'; +import PlatformViewRegistryImpl from './PlatformViewRegistryImpl'; +import DartExecutor from '../../embedding/engine/dart/DartExecutor'; +import { AccessibilityEventsDelegate } from './AccessibilityEventsDelegate'; +import AccessibilityBridge from '../../view/AccessibilityBridge'; +import { RootDvModeManager } from './RootDvModelManager'; +import { FlutterMutatorView } from '../../embedding/engine/mutatorsstack/FlutterMutatorView'; +import common from '@ohos.app.ability.common'; +import Log from '../../util/Log' +import OhosTouchProcessor from '../../embedding/ohos/OhosTouchProcessor' +import PlatformViewFactory from './PlatformViewFactory' +import { ByteBuffer } from '../../util/ByteBuffer'; + +const TAG = "PlatformViewsController" + +export default class PlatformViewsController implements PlatformViewsAccessibilityDelegate, PlatformViewsHandler { + private registry: PlatformViewRegistryImpl; + private context: Context; + private flutterView: FlutterView; + private textureRegistry: TextureRegistry; + private textInputPlugin: TextInputPlugin; + private platformViewsChannel: PlatformViewsChannel; + private accessibilityEventsDelegate: AccessibilityEventsDelegate; + private nextOverlayLayerId: number = 0; + private ohosTouchProcessor: OhosTouchProcessor; + private usesSoftwareRendering: boolean = false; + + private platformViews: Map; + private overlayLayerViews: Map; + private viewWrappers: Map; + private currentFrameUsedOverlayLayerIds: HashSet; + private currentFrameUsedPlatformViewIds: HashSet; + private rootDvModel = RootDvModeManager.getRootDvMode(); + private platformViewParent: Map; + + constructor() { + this.registry = new PlatformViewRegistryImpl(); + this.accessibilityEventsDelegate = new AccessibilityEventsDelegate(); + this.overlayLayerViews = new Map(); + this.currentFrameUsedOverlayLayerIds = new HashSet(); + this.currentFrameUsedPlatformViewIds = new HashSet(); + this.viewWrappers = new Map(); + this.platformViews = new Map(); + this.platformViewParent = new Map(); + } + + + getPlatformViewById(viewId: number): Object { + throw new Error('Method not implemented.'); + } + + usesVirtualDisplay(id: number): boolean { + throw new Error('Method not implemented.'); + } + + attachAccessibilityBridge(accessibilityBridge: AccessibilityBridge): void { + throw new Error('Method not implemented.'); + } + + detachAccessibilityBridge(): void { + throw new Error('Method not implemented.'); + } + + createForPlatformViewLayer(request: PlatformViewCreationRequest): void { + Log.i(TAG, "Enter createForPlatformViewLayer"); + this.ensureValidRequest(request); + + let platformView: PlatformView = this.createPlatformView(request, false); + + this.configureForHybridComposition(platformView, request); + } + + dispose(viewId: number): void { + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Disposing unknown platform view with id: " + viewId); + return; + } + this.platformViews.delete(viewId); + + try { + platformView.dispose(); + } catch (err) { + Log.e(TAG, "Disposing platform view threw an exception", err); + } + + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper != null) { + this.viewWrappers.delete(viewId); + } + + let parentView: FlutterMutatorView = this.platformViewParent.get(viewId); + if (parentView != null) { + this.platformViewParent.delete(viewId); + } + } + + setParams: (params: DVModelParameters, key: String, element: ESObject ) => void = (params: DVModelParameters, element: ESObject): void => { + let params2 = params as Record; + params2.key =element; + } + + resize(request: PlatformViewResizeRequest, onComplete: PlatformViewBufferResized): void { + let physicalWidth: number = this.toPhysicalPixels(request.newLogicalWidth); + let physicalHeight: number = this.toPhysicalPixels(request.newLogicalHeight); + let viewId: number = request.viewId; + Log.i(TAG, `Resize viewId ${viewId}, pw:${physicalWidth}, ph:${physicalHeight},lw:${request.newLogicalWidth}, lh:${request.newLogicalHeight}`); + + let platformView: PlatformView = this.platformViews.get(viewId); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (platformView == null || viewWrapper == null) { + Log.e(TAG, "Resizing unknown platform view with id: " + viewId); + return; + } + + let viewWrapperLayoutParams: DVModelParameters = viewWrapper.getDvModel().getLayoutParams(); + if (physicalWidth) { + this.setParams(viewWrapperLayoutParams, "width", physicalWidth); + // viewWrapperLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(viewWrapperLayoutParams, "height", physicalHeight); + // viewWrapperLayoutParams.height = physicalHeight; + } + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView != null) { + let embeddedViewLayoutParams = embeddedView.getLayoutParams(); + if (physicalWidth) { + this.setParams(embeddedViewLayoutParams, "width", physicalWidth); + // embeddedViewLayoutParams.width = physicalWidth; + } + + if (physicalHeight) { + this.setParams(embeddedViewLayoutParams, "height", physicalHeight); + // embeddedViewLayoutParams.height = physicalHeight; + } + } + + onComplete.run(new PlatformViewBufferSize(request.newLogicalWidth, request.newLogicalHeight)); + } + + offset(viewId: number, top: number, left: number): void { + Log.i(TAG, `Offset is id${viewId}, t:${top}, l:${left}`); + let viewWrapper: PlatformViewWrapper = this.viewWrappers.get(viewId); + if (viewWrapper == null) { + Log.e(TAG, "Setting offset for an unknown platform view with id: " + viewId); + return; + } + + let physicalTop = this.toPhysicalPixels(top); + let physicalLeft = this.toPhysicalPixels(left); + let params = viewWrapper.getDvModel().params; + this.setParams(params, "marginTop", physicalTop); + this.setParams(params, "marginLeft", physicalLeft); + // params.marginTop = physicalTop; + // params.marginLeft = physicalLeft; + viewWrapper.setLayoutParams(params); + } + + onTouch(touch: PlatformViewTouch): void { + let viewId: number = touch.viewId; + let density: number = display.getDefaultDisplaySync().densityDPI; + + let platformView: PlatformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Sending touch to an unknown platform view with id: " + viewId); + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + Log.e(TAG, "Sending touch to a null dv model with id: " + viewId); + } + Log.e(TAG, "Sending touch to a dv model with id: " + viewId.toString()); + sendEventByKey(viewId.toString(), 10, ""); + } + + setDirection(viewId: number, direction: number): void { + if (!this.validateDirection(direction)) { + throw new Error("Trying to set unknown direction value: " + + direction + + "(view id: " + + viewId + + ")"); + } + + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + this.setParams(embeddedView.params, "direction", direction); + // embeddedView.params.direction = direction; + } + + validateDirection(direction:number):boolean { + return direction == Direction.Ltr || direction == Direction.Rtl || direction == Direction.Auto; + } + + clearFocus(viewId: number): void { + const platformView = this.platformViews.get(viewId); + if (platformView == null) { + Log.e(TAG, "Setting direction to an unknown view with id: " + viewId); + return; + } + const embeddedView = platformView.getView(); + if (embeddedView == null) { + Log.e(TAG, "Setting direction to a null view with id: " + viewId); + return; + } + focusControl.requestFocus("flutterXComponent"); + } + synchronizeToNativeViewHierarchy(yes: boolean): void { + throw new Error('Method not implemented.'); + } + + public createForTextureLayer(request: PlatformViewCreationRequest): number { + Log.i(TAG, "Enter createForTextureLayer"); + this.ensureValidRequest(request); + + let viewId: number = request.viewId; + if (this.viewWrappers.get(request.viewId) != null) { + throw new Error( + "Trying to create an already created platform view, view id: " + viewId); + } + + let platformView: PlatformView = this.createPlatformView(request, true); + let dynamicView: DVModel = platformView.getView(); + return this.configureForTextureLayerComposition(platformView, request); + } + + private ensureValidRequest(request: PlatformViewCreationRequest): void { + if (!this.validateDirection(request.direction)) { + throw new Error("Trying to create a view with unknown direction value: " + + request.direction + + "(view id: " + + request.viewId + + ")") + } + } + + private createPlatformView(request: PlatformViewCreationRequest, wrapContext: boolean): PlatformView { + Log.i(TAG, "Enter createPlatformView"); + const viewFactory: PlatformViewFactory = this.registry.getFactory(request.viewType); + if (viewFactory == null) { + throw new Error("Trying to create a platform view of unregistered type: " + request.viewType) + } + + let createParams: ESObject = null; + if (request.params != null) { + let byteParas : ByteBuffer = request.params as ByteBuffer; + createParams = viewFactory.getCreateArgsCodec().decodeMessage(byteParas.buffer); + } + + let mutableContext: common.Context = this.context; + let platformView = viewFactory.create(mutableContext, request.viewId, createParams); + + let embeddedView: DVModel = platformView.getView(); + if (embeddedView == null) { + throw new Error("PlatformView#getView() returned null, but an dynamic view reference was expected."); + } + + this.setParams(embeddedView.params, "direction", request.direction); + // embeddedView.params.direction = request.direction; + + this.platformViews.set(request.viewId, platformView); + return platformView; + } + + // Configures the view for Hybrid Composition mode. + private configureForHybridComposition(platformView: PlatformView, request: PlatformViewCreationRequest): void { + Log.i(TAG, "Using hybrid composition for platform view: " + request.viewId); + } + + private configureForTextureLayerComposition(platformView: PlatformView, request: PlatformViewCreationRequest): number { + Log.i(TAG, "Hosting view in view hierarchy for platform view: " + request.viewId); + + let viewWrapper: PlatformViewWrapper = new PlatformViewWrapper(); + let textureId: number = 0; + + let physicalTop: number = this.toPhysicalPixels(request.logicalTop); + let physicalLeft: number = this.toPhysicalPixels(request.logicalLeft); + + Log.i(TAG, `View pW:${request.logicalWidth}, pH:${request.logicalHeight}, pT:${physicalTop}, pL:${physicalLeft}`); + + let param: DVModelParameters = new DVModelParameters(); + + this.setParams(param, "marginLeft", physicalLeft); + this.setParams(param, "marginTop", physicalTop); + // param.marginLeft = physicalLeft; + // param.marginTop = physicalTop; + + let model = platformView.getView(); + if (request.logicalWidth != null) { + let physicalWidth: number = this.toPhysicalPixels(request.logicalWidth); + this.setParams(model.params, "width", physicalWidth); + this.setParams(param, "width", physicalWidth); + // model.params.width = physicalWidth; + // param.width = physicalWidth; + } + + if (request.logicalHeight != null) { + let physicalHeight: number = this.toPhysicalPixels(request.logicalHeight); + this.setParams(model.params, "height", physicalHeight); + this.setParams(param, "height", physicalHeight); + // model.params.height = physicalHeight; + // param.height = physicalHeight; + } + + viewWrapper.setLayoutParams(param); + viewWrapper.addDvModel(model); + + RootDvModeManager.addDvModel(viewWrapper.getDvModel()); + this.viewWrappers.set(request.viewId, viewWrapper); + Log.i(TAG, "Create platform view success"); + + return textureId; + } + + public attach(context: Context, textureRegistry: TextureRegistry, dartExecutor: DartExecutor): void { + if (this.context != null) { + + } + this.context = context; + this.textureRegistry = textureRegistry; + this.platformViewsChannel = new PlatformViewsChannel(dartExecutor); + this.platformViewsChannel.setPlatformViewsHandler(this); + } + + public detach(): void { + if (this.platformViewsChannel != null) { + this.platformViewsChannel.setPlatformViewsHandler(null); + } + this.destroyOverlaySurfaces(); + this.platformViewsChannel = null; + this.context = null; + this.textureRegistry = null; + } + + public attachToView() { + for (let wrapper of this.viewWrappers.values()) { + this.rootDvModel.model.children.push(wrapper.getDvModel()); + } + for (let mutator of this.platformViewParent.values()) { + this.rootDvModel.model.children.push(mutator.getDvModel()); + } + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewAttached(this.rootDvModel.model); + } + } + + public detachFromView(): void { + for (let index = 0; index < this.viewWrappers.size; index++) { + this.rootDvModel.model.children.pop(); + } + for (let index = 0; index < this.platformViewParent.size; index++) { + this.rootDvModel.model.children.pop(); + } + this.destroyOverlaySurfaces(); + this.removeOverlaySurfaces(); + this.rootDvModel = null; + + for (let platformView of this.platformViews.values()) { + platformView.onFlutterViewDetached(); + } + } + + public attachTextInputPlugin(textInputPlugin: TextInputPlugin): void { + this.textInputPlugin = textInputPlugin; + } + + public detachTextInputPlugin(): void { + this.textInputPlugin == null; + } + + public getRegistry(): PlatformViewRegistry { + return this.registry; + } + + public onDetachedFromNapi(): void { + this.diposeAllViews(); + } + + public onPreEngineRestart(): void { + this.diposeAllViews(); + } + + private getDisplayDensity(): number { + return display.getDefaultDisplaySync().densityPixels; + } + private toPhysicalPixels(logicalPixels: number): number { + return Math.round(px2vp(logicalPixels * this.getDisplayDensity())); + } + + private toLogicalPixelsByDensity(physicalPixels: number, displayDensity: number): number { + return Math.round(physicalPixels / displayDensity); + } + + private toLogicalPixels(physicalPixels: number): number { + return this.toLogicalPixelsByDensity(physicalPixels, this.getDisplayDensity()); + } + + + private diposeAllViews(): void { + } + + private initializeRootImageViewIfNeeded(): void { + } + + initializePlatformViewIfNeeded(viewId: number): void { + let platformView: PlatformView = this.platformViews[viewId]; + if (platformView == null) { + throw new Error("Platform view hasn't been initialized from the platform view channel."); + } + if (this.platformViewParent[viewId] == null) { + return; + } + let dvModel: DVModel = platformView.getView(); + if (dvModel == null) { + throw new Error("PlatformView#getView() returned null, but an ohos dv model reference was expected."); + } + let parentView: FlutterMutatorView = new FlutterMutatorView(); + parentView.setOnDescendantFocusChangeListener(() => { + this.platformViewsChannel.invokeViewFocused(viewId); + }, () => { + if (this.textInputPlugin != null) { + this.textInputPlugin.clearTextInputClient(); + } + }); + } + + public onDisplayOverlaySurface(id: number, x: number, y: number, width: number, height: number): void { + } + + public onBeginFrame(): void { + this.currentFrameUsedOverlayLayerIds.clear(); + this.currentFrameUsedPlatformViewIds.clear(); + } + + public onEndFrame(): void { + } + + private finishFrame(isFrameRenderedUsingImageReaders: boolean): void { + } + + public createOverlaySurfaceByPlatformOverlayView(imageView: PlatformOverlayView) { + let id = this.nextOverlayLayerId++; + this.overlayLayerViews.set(id, imageView); + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + public createOverlaySurface(): FlutterOverlaySurface { + return new FlutterOverlaySurface(this.nextOverlayLayerId++); + } + + private destroyOverlaySurfaces(): void { + } + + private removeOverlaySurfaces(): void { + if (!(this.flutterView instanceof FlutterView)) { + return; + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..0cc2cb0b2cc44032d2384282013785d150162bc9 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/plugin/platform/RootDvModelManager.ets @@ -0,0 +1,74 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { DVModel, DVModelContainer, DVModelParameters } from '../../view/DynamicView/dynamicView'; +import { createDVModelFromJson } from '../../view/DynamicView/dynamicViewJson'; + +@Component +struct XComponentStruct { + private context: ESObject; + + build() { + XComponent({ id: 'flutterXComponent', type: 'texture', libraryname: 'flutter' }) + .onLoad((context) => { + this.context = context; + }) + .onDestroy(() => { + }) + } +} + +interface $$type { + param: DVModelParameters +} + +@Builder +function BuildXComponentStruct($$: $$type) { + XComponentStruct(); +} + +class DVModelJson { + compType: string + children: Array + attributes: ESObject + + constructor(compType: string, children: Array, attributes: ESObject) { + this.compType = compType + this.children = children + this.attributes = attributes + } +} + +export class RootDvModeManager { + private static xComponentModel: ESObject = + { + compType: "xComponent", + build: BuildXComponentStruct + }; + private static model: DVModel = createDVModelFromJson(new DVModelJson("Stack", [RootDvModeManager.xComponentModel], { + alignContent: Alignment.TopStart + },) + + ); + private static container: DVModelContainer = new DVModelContainer(RootDvModeManager.model); + + public static getRootDvMode(): DVModelContainer { + return RootDvModeManager.container; + } + + public static addDvModel(model: DVModel): void { + RootDvModeManager.container.model.children.push(model); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets new file mode 100644 index 0000000000000000000000000000000000000000..99a7d4b522caa6daf09b06e6feb40bcd6203abd3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ByteBuffer.ets @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * A byte buffer. + * + * Supports the following data types: + * - Bool + * - Int (8, 16, 32, 64) + * - Uint (8, 16, 32, 64) + * - BigInt (64) + * - String (utf8, utf16, and delimited) + * - TypedArray + * + */ +export class ByteBuffer { + + /** + * Creates a byte buffer. + * @param source The data source. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns A byte buffer. + */ + static from(source: ArrayBuffer, byteOffset?: number, byteLength?: number): ByteBuffer { + // if (ArrayBuffer.isView(source)) { + // byteOffset = source.byteOffset + (byteOffset || 0) + // } + const byteBuffer = new ByteBuffer() + byteBuffer.dataView = byteLength === undefined ? new DataView(source, byteOffset) : new DataView(source, byteOffset, Math.min(source.byteLength, byteLength)) + byteBuffer.mByteOffset = byteBuffer.dataView.byteOffset + return byteBuffer + } + + /** + * The dataView. + */ + private dataView: DataView + + /** + * The byte offset. + */ + mByteOffset: number = 0 + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteOffset(): number { + return this.mByteOffset + } + + /** + * The byte offset. + * @returns The byte offset. + */ + get byteLength(): number { + return this.dataView.byteLength + } + + /** + * The number of remaining bytes. + * @returns The number of bytes remaining. + */ + get bytesRemaining(): number { + return this.dataView.byteLength - this.mByteOffset + } + + hasRemaining(): boolean { + return this.mByteOffset < this.dataView.byteLength; + } + + get buffer(): ArrayBuffer { + const dataBuffer = new DataView(new ArrayBuffer(this.mByteOffset)); + for (let i = 0; i < this.mByteOffset; i++) { + dataBuffer.setUint8(i, this.dataView.getUint8(i)); + } + return dataBuffer.buffer + } + + /** + * Skips the byte offset. + * @param byteLength The byte length. + */ + skip(byteLength: number): void { + this.mByteOffset += byteLength + } + + /** + * Resets the byte offset. + */ + reset(): void { + this.mByteOffset = this.dataView.byteOffset + } + + /** + * Clears the byte buffer. + */ + clear(): void { + this.getUint8Array(0).fill(0) + } + + /** + * check buffer capacity. + */ + checkWriteCapacity(slen: number): void { + if (this.mByteOffset + slen > this.dataView.byteLength) { + let checkBuffer = new DataView(new ArrayBuffer(this.dataView.byteLength + slen + 512)); + for (let i = 0; i < this.mByteOffset; i++) { + checkBuffer.setUint8(i, this.dataView.getUint8(i)); + } + this.dataView = checkBuffer; + } + } + + /** + * Gets a boolean. + * @param byteOffset The byte offset. + */ + getBool(byteOffset: number): boolean { + return this.getInt8(byteOffset) !== 0 + } + + /** + * Reads the next boolean. + */ + readBool(): boolean { + return this.getInt8(this.mByteOffset++) !== 0 + } + + /** + * Sets a boolean. + * @param byteOffset The byte offset. + * @param value The value. + */ + setBool(byteOffset: number, value: boolean): void { + this.dataView.setInt8(byteOffset, value ? 1 : 0) + } + + /** + * Writes the next boolean. + * @param value The value. + */ + writeBool(value: boolean): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value ? 1 : 0) + } + + /** + * Gets an signed byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getInt8(byteOffset: number): number { + return this.dataView.getInt8(byteOffset) + } + + /** + * Reads the next signed byte. + * @returns The value. + */ + readInt8(): number { + return this.getInt8(this.mByteOffset++) + } + + /** + * Sets a signed byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setInt8(byteOffset: number, value: number): void { + this.dataView.setInt8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeInt8(value: number): void { + this.checkWriteCapacity(1) + this.setInt8(this.mByteOffset++, value) + } + + /** + * Gets an unsigned byte. + * @param byteOffset The byte offset. + * @returns The value. + */ + getUint8(byteOffset: number): number { + return this.dataView.getUint8(byteOffset) + } + + /** + * Reads the next unsigned byte. + * @returns The value. + */ + readUint8(): number { + return this.getUint8(this.mByteOffset++) + } + + /** + * Sets an unsigned byte. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8(byteOffset: number, value: number): void { + this.dataView.setUint8(byteOffset, value) + } + + /** + * Writes the next signed byte. + * @param value The value. + */ + writeUint8(value: number): void { + this.checkWriteCapacity(1) + this.setUint8(this.mByteOffset++, value) + } + + /** + * Gets an signed short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt16(byteOffset, littleEndian) + } + + /** + * Reads the next signed short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt16(littleEndian?: boolean): number { + const value = this.getInt16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets a signed short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setInt16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an unsigned short. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint16(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint16(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned short. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint16(littleEndian?: boolean): number { + const value = this.getUint16(this.mByteOffset, littleEndian) + this.mByteOffset += 2 + return value + } + + /** + * Sets an unsigned short. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint16(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint16(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed short. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint16(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(2) + this.setUint16(this.mByteOffset, value, littleEndian) + this.mByteOffset += 2 + } + + /** + * Gets an signed integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getInt32(byteOffset, littleEndian) + } + + /** + * Reads the next signed integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt32(littleEndian?: boolean): number { + const value = this.getInt32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a signed integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setInt32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setInt32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets an unsigned integer. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getUint32(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned integer. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint32(littleEndian?: boolean): number { + const value = this.getUint32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets an unsigned integer. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setUint32(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed integer. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setUint32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a float. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat32(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat32(byteOffset, littleEndian) + } + + /** + * Reads the next float. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat32(littleEndian?: boolean): number { + const value = this.getFloat32(this.mByteOffset, littleEndian) + this.mByteOffset += 4 + return value + } + + /** + * Sets a float. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat32(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat32(byteOffset, value, littleEndian) + } + + /** + * Writes the next float. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat32(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(4) + this.setFloat32(this.mByteOffset, value, littleEndian) + this.mByteOffset += 4 + } + + /** + * Gets a double. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getFloat64(byteOffset: number, littleEndian?: boolean): number { + return this.dataView.getFloat64(byteOffset, littleEndian) + } + + /** + * Reads the next double. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readFloat64(littleEndian?: boolean): number { + const value = this.getFloat64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a double. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setFloat64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.dataView.setFloat64(byteOffset, value, littleEndian) + } + + /** + * Writes the next double. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeFloat64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setFloat64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigInt64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigInt64(byteOffset, littleEndian) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigInt64(littleEndian?: boolean): bigint { + const value = this.getBigInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigInt64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigInt64(byteOffset, value, littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigInt64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getBigUint64(byteOffset: number, littleEndian?: boolean): bigint { + return this.dataView.getBigUint64(byteOffset, littleEndian) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readBigUint64(littleEndian?: boolean): bigint { + const value = this.getBigUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setBigUint64(byteOffset: number, value: bigint, littleEndian?: boolean): void { + this.dataView.setBigUint64(byteOffset, value, littleEndian) + } + + /** + * Writes the next unsigned long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeBigUint64(value: bigint, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setBigUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an signed long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getInt64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigInt64(byteOffset, littleEndian)) + } + + /** + * Reads the next signed long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readInt64(littleEndian?: boolean): number { + const value = this.getInt64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets a signed long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setInt64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigInt64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeInt64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setInt64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an unsigned long. + * @param byteOffset The byte offset. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + getUint64(byteOffset: number, littleEndian?: boolean): number { + return Number(this.getBigUint64(byteOffset, littleEndian)) + } + + /** + * Reads the next unsigned long. + * @param littleEndian If the value is little endian. + * @returns The value. + */ + readUint64(littleEndian?: boolean): number { + const value = this.getUint64(this.mByteOffset, littleEndian) + this.mByteOffset += 8 + return value + } + + /** + * Sets an unsigned long. + * @param byteOffset The byte offset. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + setUint64(byteOffset: number, value: number, littleEndian?: boolean): void { + this.setBigUint64(byteOffset, BigInt(value), littleEndian) + } + + /** + * Writes the next signed long. + * @param value The value. + * @param littleEndian If the value is little endian. + */ + writeUint64(value: number, littleEndian?: boolean): void { + this.checkWriteCapacity(8) + this.setUint64(this.mByteOffset, value, littleEndian) + this.mByteOffset += 8 + } + + /** + * Gets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint8Array(byteOffset: number, byteLength?: number): Uint8Array { + return new Uint8Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned bytes. + * @param byteLength The byte length. + * @returns The value. + */ + readUint8Array(byteLength?: number): Uint8Array { + const value = this.getUint8Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint8Array(byteOffset: number, value: Uint8Array): void { + const byteLength = value.byteLength + this.getUint8Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint8Array(value: Uint8Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint8Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets an array of unsigned shorts. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @returns The value. + */ + getUint16Array(byteOffset: number, byteLength?: number): Uint16Array { + if (byteLength !== undefined) { + byteLength = Math.floor(byteLength / 2) + } + return new Uint16Array(this.dataView.buffer, this.dataView.byteOffset + byteOffset, byteLength) + } + + /** + * Reads the next array of unsigned shorts. + * @param byteLength The byte length. + * @returns The value. + */ + readUint16Array(byteLength?: number): Uint16Array { + const value = this.getUint16Array(this.mByteOffset, byteLength) + this.mByteOffset += value.byteLength + return value + } + + /** + * Sets an array of unsigned bytes. + * @param byteOffset The byte offset. + * @param value The value. + */ + setUint16Array(byteOffset: number, value: Uint16Array): void { + const byteLength = value.byteLength + this.getUint16Array(byteOffset, byteLength).set(value) + } + + /** + * Writes the next array of unsigned bytes. + * @param value The value. + */ + writeUint16Array(value: Uint16Array): void { + this.checkWriteCapacity(value.byteLength) + this.setUint16Array(this.mByteOffset, value) + this.mByteOffset += value.byteLength + } + + /** + * Gets a string. + * @param byteOffset The byte offset. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + getString(byteOffset: number, byteLength?: number, byteEncoding?: string): string { + const decoder = new util.TextDecoder(byteEncoding || "utf-8") + const encoded = this.getUint8Array(byteOffset, byteLength) + return decoder.decode(encoded) + } + + /** + * Reads the next string. + * @param byteLength The byte length. + * @param byteEncoding The byte encoding. + * @returns The value. + */ + readString(byteLength?: number, byteEncoding?: string): string { + const value = this.getString(this.mByteOffset, byteLength, byteEncoding) + if (byteLength === undefined) { + this.mByteOffset = this.dataView.byteLength + } else { + this.mByteOffset += byteLength + } + return value + } + + /** + * Sets a string. + * @param byteOffset The byte offset. + * @param value The string. + * @param byteEncoding The byte encoding. + * @returns The byte length. + */ + setString(byteOffset: number, value: string, byteEncoding?: string, write?: boolean): number { + if (byteEncoding && byteEncoding !== "utf-8") { + throw new TypeError("String encoding '" + byteEncoding + "' is not supported") + } + const encoder = new util.TextEncoder() + const byteLength = Math.min(this.dataView.byteLength - byteOffset, value.length * 4) + if (write) { + this.checkWriteCapacity(byteLength) + } + const destination = this.getUint8Array(byteOffset, byteLength) + const written = encoder.encodeInto(value, destination).written + return written || 0 + } + + /** + * Writes the next a string. + * @param value The string. + * @param byteEncoding The byte encoding. + */ + writeString(value: string, byteEncoding?: string): void { + const byteLength = this.setString(this.mByteOffset, value, byteEncoding, true) + this.mByteOffset += byteLength + } + + /** + * Formats to a string. + * @param format The string format. + * @returns The string. + */ + toString(format?: string): string { + return [...this.getUint8Array(0)].map((byte: number) => { + switch(format) { + case "hex": + return ("00" + byte.toString(16)).slice(-2) + default: + return byte.toString(10) + } + }).join(" ") + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets new file mode 100644 index 0000000000000000000000000000000000000000..437b52f18049b9ba77e47350033482a06368c5c4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/Log.ets @@ -0,0 +1,122 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import HiLog from '@ohos.hilog'; + +const DOMAIN: number = 0x00FF; +const TAG = "Flutter"; +const SYMBOL = " --> "; +// const FILTER_KEYS = [ +// new RegExp('hide', "gi") +// ] + +// export function filterKey(target: any, propKey: string, descriptor: PropertyDescriptor) { +// const original = descriptor.value; +// descriptor.value = function (...args: string[]) { +// let filterResult = args.map((str) => { +// let tempStr = str +// FILTER_KEYS.forEach((filterKey) => tempStr = tempStr.replace(filterKey, "**")) +// return tempStr +// }); +// const result = original.call(this, ...filterResult); +// return result; +// }; +// } + +/** + * Basic log class + */ +export default class Log { + /** + * Outputs debug-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static d(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.DEBUG)) { + HiLog.debug(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs info-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static i(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.INFO)) { + HiLog.info(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs warning-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static w(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.WARN)) { + HiLog.warn(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs error-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static e(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.ERROR)) { + HiLog.error(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Outputs fatal-level logs. + * + * @param tag Identifies the log tag. + * @param format Indicates the log format string. + * @param args Indicates the log parameters. + * @since 7 + */ + static f(tag: string, format: string, ...args: ESObject[]) { + if (Log.isLoggable(HiLog.LogLevel.FATAL)) { + HiLog.fatal(DOMAIN, TAG, tag + SYMBOL + format, args); + } + } + + /** + * Checks whether logs of the specified tag, and level can be printed. + * + * @param tag Identifies the log tag. + * @param level log level + * @since 7 + */ + private static isLoggable(level: HiLog.LogLevel): boolean { + return HiLog.isLoggable(DOMAIN, TAG, level); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..1899f74069a24a3e250378b11ac1c9492f03b8f3 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/MessageChannelUtils.ets @@ -0,0 +1,25 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import BasicMessageChannel from '../plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '../plugin/common/BinaryMessenger'; +import StringUtils from './StringUtils'; + +export default class MessageChannelUtils { + static resizeChannelBuffer(messenger: BinaryMessenger, channel: string, newSize: number) { + const dataStr = `resize\r${channel}\r${newSize}` + messenger.send(BasicMessageChannel.CHANNEL_BUFFERS_CHANNEL, StringUtils.stringToArrayBuffer(dataStr)); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..691ea0f360b40adb266bde566c2f66292a2aa0ff --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/PathUtils.ets @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import common from '@ohos.app.ability.common'; +import fs from '@ohos.file.fs'; +import Log from './Log'; + +/** + * ohos路径获取工具 + */ +const TAG: string = "PathUtils"; + +export default class PathUtils { + static getFilesDir(context: common.Context): string { + return context.filesDir; + } + + static getCacheDirectory(context: common.Context): string { + return context.cacheDir; + } + + static getDataDirectory(context: common.Context): string { + const name = "flutter"; + const flutterDir = context.filesDir + "/" + name; + if (!fs.accessSync(flutterDir)) { + try { + fs.mkdirSync(flutterDir); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + return null; + } + } + return flutterDir; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..aeb7c554c30b5d3625851afc214dda8d31da9917 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/StringUtils.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import util from '@ohos.util' + +/** + * 默认字符串工具 + */ +export default class StringUtils { + static stringToArrayBuffer(str: string): ArrayBuffer { + let textEncoder = new util.TextEncoder("utf-8"); + return textEncoder.encodeInto(str).buffer; + } + + static arrayBufferToString(buffer: ArrayBuffer): string { + let textDecoder = util.TextDecoder.create('utf-8', { ignoreBOM : true }) + return textDecoder.decode(new Uint8Array(buffer)) + } + + static isNotEmpty(str: string): boolean { + return str && str.length > 0; + } + + static isEmpty(str: string): boolean { + return (!str) || str.length == 0; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3879f4a40ea307f7491a4808ad3b816cc98b13e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/ToolUtils.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class ToolUtils { + static isObj(object: Object): boolean { + return object && typeof (object) == 'object'; + } + + static implementsInterface(obj: ESObject, method: string): boolean { + return Reflect.has(obj, method) && typeof obj[method] === 'function' + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets new file mode 100644 index 0000000000000000000000000000000000000000..3caaadea7aa0cb84be3542be9c4595139cd25af4 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/util/TraceSection.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hiTraceMeter from '@ohos.hiTraceMeter' + +export class TraceSection { + + static taskId: number = 1; + + private static cropSectionName(sectionName: string): string { + return sectionName.length < 124 ? sectionName : sectionName.substring(0, 124) + "..."; + } + + /** + * Wraps Trace.beginSection to ensure that the line length stays below 127 code units. + * + * @param sectionName The string to display as the section name in the trace. + */ + public static begin(sectionName: string): void { + hiTraceMeter.startTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId++); + } + + /** Wraps Trace.endSection. */ + public static end(sectionName: string): void { + hiTraceMeter.finishTrace(TraceSection.cropSectionName(sectionName), TraceSection.taskId); + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets new file mode 100644 index 0000000000000000000000000000000000000000..0e08f41fe9171658365b4e2c806b075807ddc423 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/AccessibilityBridge.ets @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class AccessibilityBridge { + constructor(){ + + } +} + +export enum Action { + TAP = 1 << 0, + LONG_PRESS = 1 << 1, + SCROLL_LEFT = 1 << 2, + SCROLL_RIGHT = 1 << 3, + SCROLL_UP = 1 << 4, + SCROLL_DOWN = 1 << 5, + INCREASE = 1 << 6, + DECREASE = 1 << 7, + SHOW_ON_SCREEN = 1 << 8, + MOVE_CURSOR_FORWARD_BY_CHARACTER = 1 << 9, + MOVE_CURSOR_BACKWARD_BY_CHARACTER = 1 << 10, + SET_SELECTION = 1 << 11, + COPY = 1 << 12, + CUT = 1 << 13, + PASTE = 1 << 14, + DID_GAIN_ACCESSIBILITY_FOCUS = 1 << 15, + DID_LOSE_ACCESSIBILITY_FOCUS = 1 << 16, + CUSTOM_ACTION = 1 << 17, + DISMISS = 1 << 18, + MOVE_CURSOR_FORWARD_BY_WORD = 1 << 19, + MOVE_CURSOR_BACKWARD_BY_WORD = 1 << 20, + SET_NEXT = 1 << 21, +}; \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets new file mode 100644 index 0000000000000000000000000000000000000000..f95a9c04a7a44a99505b9882ba1291e7bfcb1604 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicView.ets @@ -0,0 +1,300 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import matrix4 from '@ohos.matrix4'; + +/** + * Dynamic View creation + * from a recursive data structure + * + * exported @Component: DynamicView + * exported view model classes: + * - DVModelContainer + * - DVModel + * - DVModelParameters + * - DVModelEvents + * - DVModelChildren + * + * The purpose of exporting the DVModel classes + * is to make them available to the converter from + * JD's XML format and the expression parser. These + * components are expected to generate and update the + * DVModel. + * + * An application written by JS should only import + * DynamicView, DVModelContainer to be used in their own ArkUI + * container view. + */ + +/** + * View Model classes + */ + +@Observed +export class DVModelParameters extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelEvents extends Object { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +@Observed +export class DVModelChildren extends Array { + /* empty, just get any instance wrapped inside an ObservedObject + with the help of the decoration */ +} + +let nextId: number = 1; + +@Observed +export class DVModel { + id_: number; + compType: string; + params: DVModelParameters; + events: DVModelEvents; + children: DVModelChildren; + builder: ESObject; + + constructor(compType: string, params: DVModelParameters, events: DVModelEvents, children: DVModelChildren, builder?: ESObject) { + this.id_ = nextId++; + this.compType = compType; + this.params = params ?? new DVModelParameters; + this.events = events; + this.children = children; + this.builder = builder; + } + + public getLayoutParams(): DVModelParameters { + return this.params; + } +} + +// includes the root DVModel objects. +export class DVModelContainer { + model: DVModel; + + constructor(model: DVModel) { + this.model = model; + } +} + +/** + DynamicView is the @Component that does all the work: + + The following 4 features are the key solution elements for dynamic View + construction and update: + + 1. The if statement decides which framework component to create. + We can not use a factory function here, because that would requite calling + a regular function inside build() or a @Builder function. + + 2. Take note of the @Builder for Row, Column containers: + These functions create DynamicView Views inside a DynamicView + view. This behaviour is why we talk about DynamicView as a 'recursive' View. + All @Builder functions are member functions of the DynamicView @Component to + retain access ('this.xyz') to its decorated state variables. + + 3. The @Extend functions execute attribute and event handler registration functions + for all attributes and events permissable on the framework component, irrespective + if DVModelParameters or DVModelEvents objects includes a value or not. If not + the attribute or event is set to 'undefined' by intention. This is required to unset + any previously set value. + + 4. The scope ('this') of any lambda registered as an event hander function, e.g. for onClick, + is the @Component, in which the DVModel object is initialized. This said, it is advised to initialize + the DVModel object in the @Component that is parent to outmost DynamicView. Thereby, + any event handler function is able to mutate decorated state variables of that @Component + + */ + +@Component +export struct DynamicView { + @ObjectLink model: DVModel; + @ObjectLink children: DVModelChildren; + @ObjectLink params: DVModelParameters; + @ObjectLink events: DVModelEvents; + @BuilderParam customBuilder?: ($$: BuilderParams) => void; + getParams: (params: DVModelParameters, element: string) => string | ESObject = (params: DVModelParameters, element: string): string | ESObject => { + let params2 = params as Record; + return params2.element; + } + getEvents: (events: DVModelEvents, element: string) => ESObject = (events: DVModelEvents, element: string): ESObject => { + let events2 = events as Record; + return events2.element; + } + + /* + we use this @Styles member function to set all common attributes and event handlers + and set component specific attribute and event handler functions in the @Builder function + */ + @Styles + common_attrs() { + // let params2 = this.params as Record | matrix4.Matrix4Transit>; + // .width(this.params["width"]) + // .height(this.params["height"]) + // .backgroundColor(this.params["backgroundColor"]) + // .onClick(this.events["onClick"]) + // .margin({ + // left: this.params["marginLeft"], + // right: this.params["marginRight"], + // top: this.params["marginTop"], + // bottom: this.params["marginBottom"] + // }) + // .onTouch(this.events["onTouch"]) + // .onFocus(this.events['onFocus']) + // .onBlur(this.events["onBlur"]) + // .translate({ + // x: this.params["translateX"], + // y: this.params["translateY"], + // z: this.params["translateZ"] + // }) + // .transform(this.params["matrix"]) + // .direction(this.params["direction"])this.getParams(this.params, "") + .width(this.getParams(this.params, "width")) + .height(this.getParams(this.params, "height")) + .backgroundColor(this.getParams(this.params, "backgroundColor")) + .onClick(this.getEvents(this.events, "onClick")) + .margin({ + left: this.getParams(this.params, "marginLeft"), + right: this.getParams(this.params, "marginRight"), + top: this.getParams(this.params, "marginTop"), + bottom: this.getParams(this.params, "marginBottom") + }) + .onTouch(this.getEvents(this.events, "onTouch")) + .onFocus(this.getEvents(this.events, "onFocus")) + .onBlur(this.getEvents(this.events, "onBlur")) + .translate({ + x: this.getParams(this.params, "translateX"), + y: this.getParams(this.params, "translateY"), + z: this.getParams(this.params, "translateZ") + }) + .transform(this.getParams(this.params, "matrix")) + .direction(this.getParams(this.params, "direction")) + } + + @Styles + clip_attrs() { + .clip(this.getParams(this.params, "rectWidth") ? new Rect({ + width: this.getParams(this.params, "rectWidth"), + height: this.getParams(this.params, "rectHeight"), + radius: this.getParams(this.params, "rectRadius") + }) : null) + .clip(this.getParams(this.params, "pathWidth") ? new Path({ + width: this.getParams(this.params, "pathWidth"), + height: this.getParams(this.params, "pathHeight"), + commands: this.getParams(this.params, "pathCommands") + }) : null) + } + + @Builder + buildChildren() { + ForEach(this.children, + (child: ESObject) => { + DynamicView({ + model: child as DVModel, + params: child.params, + events: child.events, + children: child.children, + customBuilder: child.builder + }) + }, + (child: ESObject) => `${child.id_}` + ) + } + + @Builder + buildRow() { + Row() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildColumn() { + Column() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + } + + @Builder + buildStack() { + Stack() { + this.buildChildren() + } + .common_attrs() + .clip_attrs() + .alignContent(this.getParams(this.params, "alignContent")) + } + + @Builder + buildText() { + Text(`${this.getParams(this.params, "value")}`) + .common_attrs() + .fontColor(this.getParams(this.params, "fontColor")) + } + + @Builder + buildImage() { + Image(this.getParams(this.params, "src")) + .common_attrs() + } + + // Button with label + @Builder + buildButton() { + Button(this.getParams(this.params, "value")) + .common_attrs() + } + + @Builder + buildCustom() { + if (this.customBuilder) { + this.customBuilder(new BuilderParams(this.params)); + } + } + + build() { + if (this.model.compType == "Column") { + this.buildColumn() + } else if (this.model.compType == "Row") { + this.buildRow() + } else if (this.model.compType == "Stack") { + this.buildStack() + } else if (this.model.compType == "Text") { + this.buildText() + } else if (this.model.compType == "Image") { + this.buildImage() + } else if (this.model.compType == "Button") { + this.buildButton() + } else { + this.buildCustom() + } + } +} + +export class BuilderParams { + params: DVModelParameters; + + constructor(params: DVModelParameters) { + this.params = params; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets new file mode 100644 index 0000000000000000000000000000000000000000..8b97e5e5092748f7bc9e0f3af7482921891baf0f --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/DynamicView/dynamicViewJson.ets @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import { DVModel, DVModelParameters, DVModelEvents, DVModelChildren } from "./dynamicView"; + +export function createDVModelFromJson(json: Object): DVModel { + + /* private use helper functions */ + let createChildrenFrom: (children: Array) => DVModelChildren = (children: Array): DVModelChildren => { + let result = new DVModelChildren(); + if (Array.isArray(children)) { + (children as Array).forEach(child => { + const childView = createDVModelFromJson(child); + if (childView != undefined) { + result.push(childView); + } + }); + } + return result; + } + + let setParams: (result: DVModelParameters | DVModelEvents, key: ESObject, element: Object ) => void = (result: DVModelParameters, key: ESObject, element: ESObject): void => { + let newResult = result as Record; + newResult.key = element.key; + } + + let createAttributesFrom: (attributes: Object) => DVModelParameters = (attributes: Object): DVModelParameters => { + let result = new DVModelParameters(); + if ((typeof attributes == "object") && (!Array.isArray(attributes))) { + Object.keys(attributes).forEach(k => {setParams(result, k, attributes)}); + } + return result; + } + + let createEventsFrom: (events: Object) => DVModelEvents = (events: Object): DVModelEvents => { + let result = new DVModelEvents(); + if ((typeof events == "object") && (!Array.isArray(events))) { + Object.keys(events).forEach(k => {setParams(result, k, events)}); + } + return result; + } + + if (typeof json !== 'object') { + console.error("createDVModelFromJson: input is not JSON"); + return undefined; + } + + let jsonObject = json as Record; + return new DVModel( + jsonObject.compType, + createAttributesFrom(jsonObject["attributes"]), + createEventsFrom(jsonObject["events"]), + createChildrenFrom(jsonObject["children"]), + jsonObject["build"] + ); +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets new file mode 100644 index 0000000000000000000000000000000000000000..f52152001a497e70586215af090b2a81190e1187 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterCallbackInformation.ets @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import FlutterNapi from '../embedding/engine/FlutterNapi'; + +export class FlutterCallbackInformation { + callbackName: string; + callbackClassName: string; + callbackLibraryPath: string; + + /** + * Get callback information for a given handle. + * + * @param handle the handle for the callback, generated by `PluginUtilities.getCallbackHandle` in + * `dart:ui`. + * @return an instance of FlutterCallbackInformation for the provided handle. + */ + static lookupCallbackInformation(handle: number): FlutterCallbackInformation { + return FlutterNapi.nativeLookupCallbackInformation(handle); + } + + constructor(callbackName: string, callbackClassName: string, callbackLibraryPath: string) { + this.callbackName = callbackName; + this.callbackClassName = callbackClassName; + this.callbackLibraryPath = callbackLibraryPath; + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets new file mode 100644 index 0000000000000000000000000000000000000000..9138ad728502e49e675e69e1fd533d80ad7016bc --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterNativeView.ets @@ -0,0 +1,137 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import DartExecutor from '../embedding/engine/dart/DartExecutor'; +import { EngineLifecycleListener } from '../embedding/engine/FlutterEngine'; +import FlutterNapi from '../embedding/engine/FlutterNapi'; +import Log from '../util/Log'; +import FlutterPluginRegistry from '../app/FlutterPluginRegistry'; +import FlutterRunArguments from './FlutterRunArguments'; +import { FlutterView } from './FlutterView'; + +const TAG: string = "FlutterNativeView"; + +export default class FlutterNativeView { + private mContext: common.Context; + private mPluginRegistry: FlutterPluginRegistry; + private mFlutterNapi: FlutterNapi; + private dartExecutor: DartExecutor; + private mFlutterView: FlutterView; + private applicationIsRunning: boolean; + + constructor(context: common.Context, isBackgroundView?: boolean) { + if (isBackgroundView) { + Log.i(TAG, "isBackgroundView is no longer supported and will be ignored"); + } + this.mContext = context; + this.mPluginRegistry = new FlutterPluginRegistry(); + this.mFlutterNapi = new FlutterNapi(); + //this.mFlutterNapi.addIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.dartExecutor = new DartExecutor(this.mFlutterNapi, this.mContext.resourceManager); + this.mFlutterNapi.addEngineLifecycleListener(new EngineLifecycleListenerImpl(this.mFlutterView, this.mPluginRegistry)); + this.attach(this.mFlutterNapi, this.dartExecutor); + this.assertAttached(this.mFlutterNapi); + } + + attach(flutterNapi: FlutterNapi, dartExecutor: DartExecutor): void { + flutterNapi.attachToNative(); + dartExecutor.onAttachedToNAPI(); + } + + assertAttached(flutterNapi: FlutterNapi): void { + if (!this.isAttached(flutterNapi)) { + throw new Error('Platform View is not attached'); + } + } + + isAttached(flutterNapi: FlutterNapi): boolean { + return flutterNapi.isAttached(); + } + + detachFromFlutterView(): void { + this.mPluginRegistry.detach(); + this.mFlutterView = null; + } + + destroy(): void { + this.mPluginRegistry.destroy(); + this.dartExecutor.onDetachedFromNAPI(); + this.mFlutterView = null; + //this.mFlutterNapi.removeIsDisplayingFlutterUiListener(this.flutterUiDisplayListener); + this.applicationIsRunning = false; + } + + getDartExecutor(): DartExecutor { + return this.dartExecutor; + } + + getPluginRegistry(): FlutterPluginRegistry { + return this.mPluginRegistry; + } + + attachViewAndAbility(flutterView: FlutterView, context: common.Context): void { + this.mFlutterView = flutterView; + this.mPluginRegistry.attach(flutterView, context); + } + + runFromBundle(args: FlutterRunArguments): void { + if (args.entrypoint == null) { + throw new Error("an entrypoint must be specific"); + } + this.assertAttached(this.mFlutterNapi); + if (this.applicationIsRunning) { + throw new Error("this flutter engine instance is already running an application"); + } + this.mFlutterNapi.runBundleAndSnapshotFromLibrary(args.bundlePath, args.entrypoint, args.libraryPath, this.mContext.resourceManager, null); + this.applicationIsRunning = true; + } + + isApplicationRunning(): boolean { + return this.applicationIsRunning; + } + + // getObservatoryUri(): string { + // return this.mFlutterNapi.getObservatoryUri(); + // } +} + +class EngineLifecycleListenerImpl implements EngineLifecycleListener { + private flutterView: FlutterView; + private pluginRegistry: FlutterPluginRegistry; + + onPreEngineRestart(): void { + if (this.flutterView != null) { + //this.flutterView.resetAccessibilityTree(); + } + + if (this.pluginRegistry == null) { + return; + } + + this.pluginRegistry.onPreEngineRestart(); + } + + onEngineWillDestroy(): void { + + } + + constructor(flutterView: FlutterView, pluginRegistry: FlutterPluginRegistry) { + this.flutterView = flutterView; + this.pluginRegistry = pluginRegistry; + } +} + + diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets new file mode 100644 index 0000000000000000000000000000000000000000..d17ec28d1fdc6237ee486362751ee25e58590887 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterRunArguments.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export default class FlutterRunArguments { + public bundlePath: string; + public entrypoint: string; + public libraryPath: string; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets new file mode 100644 index 0000000000000000000000000000000000000000..cf38a74159eb41c2ca4b6ede7f9e04e0cc66bf5a --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/FlutterView.ets @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class FlutterView { + +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets new file mode 100644 index 0000000000000000000000000000000000000000..1f100263589238f2d354ccf92636ab46fb03d040 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/ets/view/TextureRegistry.ets @@ -0,0 +1,37 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +export interface TextureRegistry { + + createSurfaceTexture(): SurfaceTextureEntry; + registerSurfaceTexture(): SurfaceTextureEntry; + + onTrimMemory(level: number) : void; +} + +interface SurfaceTextureEntry { + id(): number; + + release(): void; +} + +interface OnFrameConsumedListener { + onFrameConsumed(): void; +} + +interface OnTrimMemoryListener { + onTrimMemory(level: number) : void; +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json new file mode 100644 index 0000000000000000000000000000000000000000..14c854f518a6a4f98ef7ece63da2e957ab98f69e --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/module.json @@ -0,0 +1,35 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "bundleName": "net.openvalley.helloworld", + "debug": true, + "versionCode": 1000000, + "versionName": "1.0.0", + "minAPIVersion": 40000010, + "targetAPIVersion": 40000010, + "apiReleaseType": "Release", + "compileSdkVersion": "4.0.0.40", + "compileSdkType": "HarmonyOS" + }, + "module": { + "name": "flutter_embedding", + "type": "har", + "deviceTypes": [ + "default" + ] + } +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/oh_modules/@ohos/flutter_ohos/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..86898f1769b5757a9956c56bbdf71250aacb49b0 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/Messages.ets @@ -0,0 +1,249 @@ +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; + +export enum StorageDirectory { + ROOT = 0, + MUSIC = 1, + PODCASTS = 2, + RINGTONES = 3, + ALARMS = 4, + NOTIFICATIONS = 5, + PICTURES = 6, + MOVIES = 7, + DOWNLOADS = 8, + DCIM = 9, + DOCUMENTS = 10 +} + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class PathProviderApi { + abstract getTemporaryPath(): string; + + abstract getApplicationSupportPath(): string; + + abstract getApplicationDocumentsPath(): string; + + abstract getApplicationCachePath(): string; + + abstract getExternalStoragePath(): string; + + abstract getExternalCachePaths(): Array; + + abstract getExternalStoragePaths(directory: StorageDirectory): Array; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: PathProviderApi) { + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getTemporaryPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getTemporaryPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationSupportPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationSupportPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationDocumentsPath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationDocumentsPath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getApplicationCachePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getApplicationCachePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePath", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalStoragePath(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalCachePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + try { + const output = api.getExternalCachePaths(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + { + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.PathProviderApi.getExternalStoragePaths", + PathProviderApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "setup on message : " + message); + let wrapped: Array = new Array(); + let args: Array = message; + const directoryArg: StorageDirectory = args[0] == null ? null : args[0]; + try { + const output = api.getExternalStoragePaths(directoryArg); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..dd172ef16a6bb11e51f9eed062a200065c9fcdb5 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin.ets @@ -0,0 +1,157 @@ +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import PathUtils from '@ohos/flutter_ohos/src/main/ets/util/PathUtils'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { PathProviderApi, StorageDirectory } from './Messages'; +import fs from '@ohos.file.fs'; + +const TAG: string = "PathProviderPlugin"; + +export default class PathProviderPlugin extends PathProviderApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding; + private context: common.Context; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "onAttachedToAbility"); + this.setup(this.pluginBinding.getBinaryMessenger(), this.pluginBinding.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + PathProviderApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up PathProviderPlugin", err); + } + this.context = context; + } + + getTemporaryPath(): string { + return this.getPathProviderTemporaryDirectory(); + } + + getApplicationSupportPath(): string { + return this.getApplicationSupportDirectory(); + } + + getApplicationDocumentsPath(): string { + return this.getPathProviderApplicationDocumentsDirectory(); + } + + getApplicationCachePath(): string { + return this.context.cacheDir; + } + + getExternalStoragePath(): string { + return this.getPathProviderStorageDirectory(); + } + + getExternalCachePaths(): Array { + return this.getPathProviderExternalCacheDirectories(); + } + + getExternalStoragePaths(directory: StorageDirectory): Array { + return this.getPathProviderExternalStorageDirectories(directory); + } + + private getPathProviderTemporaryDirectory(): string { + return this.context.tempDir; + } + + private getApplicationSupportDirectory(): string { + return PathUtils.getFilesDir(this.context); + } + + private getPathProviderApplicationDocumentsDirectory(): string { + return PathUtils.getDataDirectory(this.context); + } + + private getPathProviderStorageDirectory(): string { + return this.context.filesDir; + } + + private getPathProviderExternalCacheDirectories(): Array { + const paths = new Array(); + paths.push(this.context.cacheDir); + return paths; + } + + private getStorageDirectoryString(directory: StorageDirectory): string { + switch (directory) { + case StorageDirectory.ROOT: + return ""; + case StorageDirectory.MUSIC: + return "music"; + case StorageDirectory.PODCASTS: + return "podcasts"; + case StorageDirectory.RINGTONES: + return "ringtones"; + case StorageDirectory.ALARMS: + return "alarms"; + case StorageDirectory.NOTIFICATIONS: + return "notifications"; + case StorageDirectory.PICTURES: + return "pictures"; + case StorageDirectory.MOVIES: + return "movies"; + case StorageDirectory.DOWNLOADS: + return "downloads"; + case StorageDirectory.DCIM: + return "dcim"; + case StorageDirectory.DOCUMENTS: + return "documents"; + default: + throw new Error("Unrecognized directory: " + directory); + } + } + + private getPathProviderExternalStorageDirectories(directory: StorageDirectory): Array { + const paths = new Array(); + const filePath = this.context.filesDir + "/" + this.getStorageDirectoryString(directory); + if (!fs.accessSync(filePath)) { + try { + fs.mkdirSync(filePath); + paths.push(filePath); + Log.i(TAG, "no directory " + filePath + " create success"); + } catch (err) { + Log.e(TAG, "mkdirSync failed err:" + err); + } + } else { + paths.push(filePath); + } + + return paths; + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..60b8ccf90ec0b30522a0fa1bd37fc25ad813b174 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/module.json5 @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + + +{ + "module": { + "name": "path_provider", + "type": "har", + "deviceTypes": [ + "default", + "tablet" + ] + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/en_US/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1e76de0c66777cfe83568615c5c2e68c61d23fed --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "page_show", + "value": "page from npm package" + } + ] +} diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..12ddf6a9a9e09489e6c97403e95cb9ae8acccd9d --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/List.test.ets @@ -0,0 +1,5 @@ +import localUnitTest from './LocalUnit.test'; + +export default function testsuite() { + localUnitTest() +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..2b2dd4f1d969e706afc3a52f1b472ae099f65330 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/ohos/path_provider/src/test/LocalUnit.test.ets @@ -0,0 +1,33 @@ +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium'; + +export default function localUnitTest() { + describe('localUnitTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }); + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }); + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }); + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }); + it('assertContain', 0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + let a = 'abc'; + let b = 'b'; + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b); + expect(a).assertEqual(a); + }); + }); +} \ No newline at end of file diff --git a/ohos/test_octo_image/lib/path_provider_ohos/pubspec.yaml b/ohos/test_octo_image/lib/path_provider_ohos/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..941cd6c41ec5db0c707af357b12407c8497c9594 --- /dev/null +++ b/ohos/test_octo_image/lib/path_provider_ohos/pubspec.yaml @@ -0,0 +1,46 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: path_provider_ohos +description: Ohos implementation of the path_provider plugin. +repository: https://github.com/flutter/packages/tree/main/packages/path_provider/path_provider_ohos +issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+path_provider%22 +version: 1.0.0 + +environment: + sdk: ">=2.18.0 <4.0.0" + flutter: ">=3.3.0" + +flutter: + plugin: + implements: path_provider + platforms: + ohos: + package: io.flutter.plugins.pathprovider + pluginClass: PathProviderPlugin + dartPluginClass: PathProviderOhos + +dependencies: + flutter: + sdk: flutter + path_provider_platform_interface: ^2.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + integration_test: + sdk: flutter + pigeon: ^9.2.4 + test: ^1.16.0 diff --git a/ohos/test_octo_image/ohos/.gitignore b/ohos/test_octo_image/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_octo_image/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/AppScope/app.json5 b/ohos/test_octo_image/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e308742b3c7e6a52c7fa3f829da223514d944b21 --- /dev/null +++ b/ohos/test_octo_image/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_octo_image", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_octo_image/ohos/AppScope/resources/base/element/string.json b/ohos/test_octo_image/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..3689029193f507d84204bec084412753ed16c2f0 --- /dev/null +++ b/ohos/test_octo_image/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_octo_image" + } + ] +} diff --git a/ohos/test_octo_image/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_octo_image/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_octo_image/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_octo_image/ohos/build-profile.json5 b/ohos/test_octo_image/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..38a1032f84e348f34b09961108c361a437c0229d --- /dev/null +++ b/ohos/test_octo_image/ohos/build-profile.json5 @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_octo_image.cer", + "storePassword": "0000001A79B8052CFEA4052B0508F8E1E5ADF01C82DDB785813D89A256A4D8806DC49962B97E78DA7B08", + "keyAlias": "debugKey", + "keyPassword": "0000001AC6BFCF352DB3C133DA9557241BB3616992DDE9768E75D00B14934CBE193AB40EE0C2DF2119BE", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_octo_image.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_octo_image.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_octo_image/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_octo_image/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_octo_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_octo_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_octo_image/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_octo_image/ohos/dependencies/rollup.tgz b/ohos/test_octo_image/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_octo_image/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_octo_image/ohos/dta/icudtl.dat b/ohos/test_octo_image/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_octo_image/ohos/dta/icudtl.dat differ diff --git a/ohos/test_octo_image/ohos/entry/.gitignore b/ohos/test_octo_image/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/build-profile.json5 b/ohos/test_octo_image/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/hvigorfile.ts b/ohos/test_octo_image/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_octo_image/ohos/entry/oh-package.json5 b/ohos/test_octo_image/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc825b2605dfa662e22ef0c07c800935c687706d --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/oh-package.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har", + "@ohos/path_provider": "file:../har/path_provider.har" + } +} diff --git a/ohos/test_octo_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_octo_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..f442fca52ad19b04b9969d648bf549273b0a6c9b --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import PathProviderPlugin from '@ohos/path_provider/src/main/ets/io/flutter/plugins/pathprovider/PathProviderPlugin' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + this.addPlugin(new PathProviderPlugin()) + } +} diff --git a/ohos/test_octo_image/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_octo_image/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/module.json5 b/ohos/test_octo_image/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_octo_image/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_octo_image/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_octo_image/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3abf18c41c58c933308c244a875bf383856e103e --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]}] \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..10e90c97fa3404abf80ae48ee3c45801f48cb1df Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..e5e658ad83ca596ed32e2850258c0b163440abb2 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_octo_image/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_octo_image/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/module.json5 b/ohos/test_octo_image/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_octo_image/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_octo_image/ohos/har/flutter_embedding.har b/ohos/test_octo_image/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_octo_image/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_octo_image/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.10 b/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.9 b/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_octo_image/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_octo_image/ohos/har/libflutter.so.debug.10 b/ohos/test_octo_image/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_octo_image/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_octo_image/ohos/har/libflutter.so.release.10 b/ohos/test_octo_image/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_octo_image/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_octo_image/ohos/har/path_provider.har b/ohos/test_octo_image/ohos/har/path_provider.har new file mode 100644 index 0000000000000000000000000000000000000000..8c59d9becc7b85514cdf262b804216c32a856cbb Binary files /dev/null and b/ohos/test_octo_image/ohos/har/path_provider.har differ diff --git a/ohos/test_octo_image/ohos/hvigor/hvigor-config.json5 b/ohos/test_octo_image/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_octo_image/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_octo_image/ohos/hvigor/hvigor-wrapper.js b/ohos/test_octo_image/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_octo_image/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/hvigorfile.ts b/ohos/test_octo_image/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_octo_image/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/hvigorw b/ohos/test_octo_image/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_octo_image/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_octo_image/ohos/hvigorw.bat b/ohos/test_octo_image/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_octo_image/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_octo_image/ohos/oh-package-lock.json5 b/ohos/test_octo_image/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..8117ee588b7b4e9899feee78e294b5fbb14fbc3f --- /dev/null +++ b/ohos/test_octo_image/ohos/oh-package-lock.json5 @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_octo_image/ohos/oh-package.json5 b/ohos/test_octo_image/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e3458fa8c74f2151b89cc92d0190ee971acf49af --- /dev/null +++ b/ohos/test_octo_image/ohos/oh-package.json5 @@ -0,0 +1,27 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_octo_image/pubspec.yaml b/ohos/test_octo_image/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..a4ed83f3c95227bc6aa6829dfc150000dfc72b52 --- /dev/null +++ b/ohos/test_octo_image/pubspec.yaml @@ -0,0 +1,32 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_octo_image +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + octo_image: 2.0.0 + http: ^0.13.0 + path_provider_platform_interface: ^2.0.0 + path_provider_ohos: + path: ./lib/path_provider_ohos +flutter: + uses-material-design: true diff --git a/ohos/test_photo_view/.gitignore b/ohos/test_photo_view/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_photo_view/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_photo_view/.metadata b/ohos/test_photo_view/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_photo_view/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_photo_view/README.md b/ohos/test_photo_view/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_photo_view/analysis_options.yaml b/ohos/test_photo_view/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_photo_view/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_photo_view/assets/firefox.svg b/ohos/test_photo_view/assets/firefox.svg new file mode 100644 index 0000000000000000000000000000000000000000..87caae6a7913afafb1adcaa9147149a6d7be6ad6 --- /dev/null +++ b/ohos/test_photo_view/assets/firefox.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + firefox-logo + + + + + + + + + + + + + + + + + diff --git a/ohos/test_photo_view/assets/fonts/ptasans-bold.ttf b/ohos/test_photo_view/assets/fonts/ptasans-bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cc597adad9da682d3acf93276acbcb33af326d1c Binary files /dev/null and b/ohos/test_photo_view/assets/fonts/ptasans-bold.ttf differ diff --git a/ohos/test_photo_view/assets/fonts/ptasans-regular.ttf b/ohos/test_photo_view/assets/fonts/ptasans-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c1249393df577f661863948f3d128dd98fea485b Binary files /dev/null and b/ohos/test_photo_view/assets/fonts/ptasans-regular.ttf differ diff --git a/ohos/test_photo_view/assets/gallery1.jpg b/ohos/test_photo_view/assets/gallery1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..15fc8ceabb0d87e47bde07029ee1970e3e369aaf Binary files /dev/null and b/ohos/test_photo_view/assets/gallery1.jpg differ diff --git a/ohos/test_photo_view/assets/gallery2.jpg b/ohos/test_photo_view/assets/gallery2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..766398d06568e9a8f3f60ab31f4af31b5da83435 Binary files /dev/null and b/ohos/test_photo_view/assets/gallery2.jpg differ diff --git a/ohos/test_photo_view/assets/gallery3.jpg b/ohos/test_photo_view/assets/gallery3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b3e67e7ba7452330821736efd8bddace84ae1df Binary files /dev/null and b/ohos/test_photo_view/assets/gallery3.jpg differ diff --git a/ohos/test_photo_view/assets/large-image.jpg b/ohos/test_photo_view/assets/large-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..67c1bc9228fec86c060b4f851eb8403ed784dfec Binary files /dev/null and b/ohos/test_photo_view/assets/large-image.jpg differ diff --git a/ohos/test_photo_view/assets/neat.gif b/ohos/test_photo_view/assets/neat.gif new file mode 100644 index 0000000000000000000000000000000000000000..438b1109aa146ad0504252c15ddb7277099d430a Binary files /dev/null and b/ohos/test_photo_view/assets/neat.gif differ diff --git a/ohos/test_photo_view/assets/small-image.jpg b/ohos/test_photo_view/assets/small-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ae2739442fb371e47e26d9f4451f53dc1514a01 Binary files /dev/null and b/ohos/test_photo_view/assets/small-image.jpg differ diff --git a/ohos/test_photo_view/graphics/test.jpg b/ohos/test_photo_view/graphics/test.jpg new file mode 100644 index 0000000000000000000000000000000000000000..14c5a6ba4787e38177ddb356e978e21d88d92ee0 Binary files /dev/null and b/ohos/test_photo_view/graphics/test.jpg differ diff --git a/ohos/test_photo_view/lib/main.dart b/ohos/test_photo_view/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..268d8d8fe298580e967eda72fbe07108ae92c7d9 --- /dev/null +++ b/ohos/test_photo_view/lib/main.dart @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:flutter/material.dart'; +import './screens/home_screen.dart'; + +void main() { + HttpOverrides.global = GlobalHttpOverrides(); + runApp(MyApp()); +} + +ThemeData theme = ThemeData( + primaryColor: Colors.blue, + backgroundColor: Colors.white10, + fontFamily: 'PTSans', +); + +class MyApp extends StatelessWidget { + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + title: 'Photo View Example App', + theme: theme, + home: Scaffold( + body: HomeScreen(), + ), + ); + } +} + +class GlobalHttpOverrides extends HttpOverrides { + @override + HttpClient createHttpClient(SecurityContext? context) { + // TODO: implement createHttpClient + return super.createHttpClient(context) + ..badCertificateCallback = + (X509Certificate cert, String host, int port) => true; + } +} diff --git a/ohos/test_photo_view/lib/screens/common/app_bar.dart b/ohos/test_photo_view/lib/screens/common/app_bar.dart new file mode 100644 index 0000000000000000000000000000000000000000..60580a1dc10fa298ca8e3dffc8d775a281ec619a --- /dev/null +++ b/ohos/test_photo_view/lib/screens/common/app_bar.dart @@ -0,0 +1,101 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +class ExampleAppBar extends StatelessWidget { + const ExampleAppBar({required this.title, this.showGoBack = false}) : super(); + + final String title; + final bool showGoBack; + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Container( + padding: const EdgeInsets.fromLTRB(20.0, 5.0, 20.0, 5.0), + decoration: const BoxDecoration( + color: Colors.white, + borderRadius: const BorderRadius.only( + bottomLeft: const Radius.circular(10.0), + bottomRight: const Radius.circular(10.0), + ), + boxShadow: [ + const BoxShadow( + color: Colors.black12, spreadRadius: 10.0, blurRadius: 20.0) + ]), + child: Row( + children: [ + Container( + child: showGoBack + ? IconButton( + icon: const Icon(Icons.chevron_left), + onPressed: () { + Navigator.pop(context); + }, + padding: EdgeInsets.zero, + ) + : Container( + height: 50.0, + ), + ), + Expanded( + child: Text( + title, + style: const TextStyle( + fontSize: 25.0, fontWeight: FontWeight.w700), + ), + ) + ], + ), + ), + ); + } +} + +class ExampleAppBarLayout extends StatelessWidget { + const ExampleAppBarLayout({ + Key? key, + required this.title, + this.showGoBack = false, + required this.child, + }) : super(key: key); + + final String title; + final bool showGoBack; + final Widget child; + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromARGB(255, 255, 255, 255), + body: Container( + height: MediaQuery.of(context).size.height, + child: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + ExampleAppBar( + title: title, + showGoBack: showGoBack, + ), + Expanded( + child: child, + ), + ], + ), + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/common/common_example_wrapper.dart b/ohos/test_photo_view/lib/screens/common/common_example_wrapper.dart new file mode 100644 index 0000000000000000000000000000000000000000..0784f56e1f215b619da0b90257ccc43b523adb6d --- /dev/null +++ b/ohos/test_photo_view/lib/screens/common/common_example_wrapper.dart @@ -0,0 +1,66 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; + +class CommonExampleRouteWrapper extends StatelessWidget { + const CommonExampleRouteWrapper({ + this.imageProvider, + this.loadingBuilder, + this.backgroundDecoration, + this.minScale, + this.maxScale, + this.initialScale, + this.basePosition = Alignment.center, + this.filterQuality = FilterQuality.none, + this.disableGestures, + this.errorBuilder, + }); + + final ImageProvider? imageProvider; + final LoadingBuilder? loadingBuilder; + final BoxDecoration? backgroundDecoration; + final dynamic minScale; + final dynamic maxScale; + final dynamic initialScale; + final Alignment basePosition; + final FilterQuality filterQuality; + final bool? disableGestures; + final ImageErrorWidgetBuilder? errorBuilder; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + constraints: BoxConstraints.expand( + height: MediaQuery.of(context).size.height, + ), + child: PhotoView( + imageProvider: imageProvider, + loadingBuilder: loadingBuilder, + backgroundDecoration: backgroundDecoration, + minScale: minScale, + maxScale: maxScale, + initialScale: initialScale, + basePosition: basePosition, + filterQuality: filterQuality, + disableGestures: disableGestures, + errorBuilder: errorBuilder, + ), + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/common/example_button.dart b/ohos/test_photo_view/lib/screens/common/example_button.dart new file mode 100644 index 0000000000000000000000000000000000000000..1663d99dc26c8cd04e463fac0eb6762faa30671a --- /dev/null +++ b/ohos/test_photo_view/lib/screens/common/example_button.dart @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +class ExampleButtonNode extends StatelessWidget { + const ExampleButtonNode({ + required this.title, + required this.onPressed, + }); + + final String title; + final VoidCallback onPressed; + + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.symmetric( + vertical: 20.0, + ), + child: Column( + children: [ + Text( + title, + textAlign: TextAlign.center, + style: const TextStyle( + color: Colors.black, + fontSize: 21.0, + fontWeight: FontWeight.w600, + ), + ), + Container( + margin: const EdgeInsets.only( + top: 10.0, + ), + child: ElevatedButton( + onPressed: onPressed, + child: const Text("查看效果"), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.amber), + ), + ), + ) + ], + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/common_use_cases_examples.dart b/ohos/test_photo_view/lib/screens/examples/common_use_cases_examples.dart new file mode 100644 index 0000000000000000000000000000000000000000..f99ac7196ed7d7b42ce12acf67ed9cb36ba52328 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/common_use_cases_examples.dart @@ -0,0 +1,194 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; +import 'package:test_photo_view/screens/common/common_example_wrapper.dart'; +import 'package:test_photo_view/screens/common/example_button.dart'; + +class CommonUseCasesExamples extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "常见用例", + showGoBack: true, + child: ListView( + children: [ + ExampleButtonNode( + title: "大图像", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "大图像(滤镜质量:中等)", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + filterQuality: FilterQuality.medium, + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "小图像(自定义背景)", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/small-image.jpg"), + backgroundDecoration: BoxDecoration( + gradient: LinearGradient( + colors: [Colors.white, Colors.grey], + stops: [0.1, 1.0], + ), + ), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "小图像(自定义对齐)", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/small-image.jpg"), + backgroundDecoration: BoxDecoration( + color: Colors.white, + ), + basePosition: Alignment(0.5, 0.0), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "动画gif", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/neat.gif"), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "规模有限", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + minScale: PhotoViewComputedScale.contained * 0.8, + maxScale: PhotoViewComputedScale.covered * 1.1, + initialScale: PhotoViewComputedScale.covered * 1.1, + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "自定义初始比例", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + initialScale: PhotoViewComputedScale.contained * 0.7, + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "点击一次即可解除", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const OneTapWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "没有手势 ", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const AssetImage("assets/large-image.jpg"), + disableGestures: true, + ), + ), + ); + }, + ), + ], + ), + ); + } +} + +class OneTapWrapper extends StatelessWidget { + const OneTapWrapper({ + required this.imageProvider, + }); + + final ImageProvider imageProvider; + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + constraints: BoxConstraints.expand( + height: MediaQuery.of(context).size.height, + ), + child: GestureDetector( + onTapDown: (_) { + Navigator.pop(context); + }, + child: PhotoView( + imageProvider: imageProvider, + ), + ), + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/controller_example.dart b/ohos/test_photo_view/lib/screens/examples/controller_example.dart new file mode 100644 index 0000000000000000000000000000000000000000..0eab204f4eae6cec30ecc32e575d60e4f629c5bc --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/controller_example.dart @@ -0,0 +1,174 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:math'; + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class ControllerExample extends StatefulWidget { + @override + _ControllerExampleState createState() => _ControllerExampleState(); +} + +const double min = pi * -2; +const double max = pi * 2; + +const double minScale = 0.03; +const double defScale = 0.1; +const double maxScale = 0.6; + +class _ControllerExampleState extends State { + late PhotoViewControllerBase controller; + late PhotoViewScaleStateController scaleStateController; + + int calls = 0; + + @override + void initState() { + controller = PhotoViewController(initialScale: defScale) + ..outputStateStream.listen(onController); + + scaleStateController = PhotoViewScaleStateController() + ..outputScaleStateStream.listen(onScaleState); + super.initState(); + } + + void onController(PhotoViewControllerValue value) { + setState(() { + calls += 1; + }); + } + + void onScaleState(PhotoViewScaleState scaleState) { + print(scaleState); + } + + @override + void dispose() { + controller.dispose(); + scaleStateController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "Controller", + showGoBack: true, + child: ClipRect( + child: Stack( + children: [ + Positioned.fill( + child: PhotoView( + imageProvider: const AssetImage("assets/large-image.jpg"), + controller: controller, + scaleStateController: scaleStateController, + enableRotation: true, + initialScale: minScale * 1.5, + minScale: minScale, + maxScale: maxScale, + ), + ), + Positioned( + bottom: 0, + height: 290, + left: 0, + right: 0, + child: Container( + padding: const EdgeInsets.all(30.0), + child: StreamBuilder( + stream: controller.outputStateStream, + initialData: controller.value, + builder: _streamBuild, + ), + ), + ) + ], + ), + ), + ); + } + + Widget _streamBuild(BuildContext context, AsyncSnapshot snapshot) { + if (snapshot.hasError || !snapshot.hasData) { + return Container(); + } + final PhotoViewControllerValue value = snapshot.data; + return Column( + children: [ + Text( + "Rotation ${value.rotation}", + style: const TextStyle(color: Colors.white), + ), + SliderTheme( + data: SliderTheme.of(context).copyWith( + activeTrackColor: Colors.orange, + thumbColor: Colors.orange, + ), + child: Slider( + value: value.rotation.clamp(min, max), + min: min, + max: max, + onChanged: (double newRotation) { + controller.rotation = newRotation; + }, + ), + ), + Text( + "Scale ${value.scale}", + style: const TextStyle(color: Colors.white), + ), + SliderTheme( + data: SliderTheme.of(context).copyWith( + activeTrackColor: Colors.orange, + thumbColor: Colors.orange, + ), + child: Slider( + value: value.scale!.clamp(minScale, maxScale), + min: minScale, + max: maxScale, + onChanged: (double newScale) { + controller.scale = newScale; + }, + ), + ), + Text( + "Position ${value.position.dx}", + style: const TextStyle(color: Colors.white), + ), + SliderTheme( + data: SliderTheme.of(context).copyWith( + activeTrackColor: Colors.orange, + thumbColor: Colors.orange, + ), + child: Slider( + value: value.position.dx, + min: -1000.0, + max: 1000.0, + onChanged: (double newPosition) { + controller.position = Offset(newPosition, controller.position.dy); + }, + ), + ), + Text( + "ScaleState ${scaleStateController.scaleState}", + style: const TextStyle(color: Colors.white), + ), + ], + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/custom_child_examples.dart b/ohos/test_photo_view/lib/screens/examples/custom_child_examples.dart new file mode 100644 index 0000000000000000000000000000000000000000..1c6b48ef3845c463ac15c7d235f5144298312b1e --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/custom_child_examples.dart @@ -0,0 +1,71 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/flutter_svg.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class CustomChildExample extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "一个显示可缩放子对象的小部件", + showGoBack: true, + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(20.0), + child: const Text( + "与图像不同的东西的用法示例", + style: const TextStyle(fontSize: 18.0), + ), + ), + Container( + margin: const EdgeInsets.symmetric( + vertical: 20.0, + horizontal: 20.0, + ), + height: 450.0, + child: ClipRect( + child: PhotoView.customChild( + child: Container( + decoration: + const BoxDecoration(color: Colors.lightGreenAccent), + padding: const EdgeInsets.all(10.0), + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text( + "你好,这是一个文本,那是一个svg:", + style: const TextStyle(fontSize: 12.0), + textAlign: TextAlign.center, + ), + SvgPicture.asset( + "assets/firefox.svg", + height: 250.0, + ) + ], + ), + ), + initialScale: 1.0, + ), + ), + ), + ], + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/dialog_example.dart b/ohos/test_photo_view/lib/screens/examples/dialog_example.dart new file mode 100644 index 0000000000000000000000000000000000000000..05cb44c0a81f28319b652702e7ccc4ee0e4ecde6 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/dialog_example.dart @@ -0,0 +1,110 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class DialogExample extends StatefulWidget { + @override + _DialogExampleState createState() => _DialogExampleState(); +} + +class _DialogExampleState extends State { + void openDialog(BuildContext context) => showDialog( + context: context, + builder: (BuildContext context) { + return Dialog( + child: Container( + child: PhotoView( + tightMode: true, + imageProvider: const AssetImage("assets/large-image.jpg"), + heroAttributes: const PhotoViewHeroAttributes(tag: "someTag"), + ), + ), + ); + }, + ); + + void openBottomSheet(BuildContext context) => showBottomSheet( + context: context, + backgroundColor: Colors.transparent, + shape: const ContinuousRectangleBorder(), + builder: (BuildContext context) { + return PhotoViewGestureDetectorScope( + axis: Axis.vertical, + child: PhotoView( + backgroundDecoration: BoxDecoration( + color: Colors.black.withAlpha(240), + ), + imageProvider: const AssetImage("assets/large-image.jpg"), + heroAttributes: const PhotoViewHeroAttributes(tag: "someTag"), + ), + ); + }, + ); + + void openBottomSheetModal(BuildContext context) => showModalBottomSheet( + context: context, + shape: const ContinuousRectangleBorder(), + builder: (BuildContext context) { + return SafeArea( + child: Container( + height: 250, + child: PhotoViewGestureDetectorScope( + axis: Axis.vertical, + child: PhotoView( + tightMode: true, + imageProvider: const AssetImage("assets/large-image.jpg"), + heroAttributes: const PhotoViewHeroAttributes(tag: "someTag"), + ), + ), + ), + ); + }, + ); + + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "集成到对话框", + showGoBack: true, + child: Builder( + builder: (context) => Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Container( + decoration: const BoxDecoration(color: Colors.red), + ), + ElevatedButton( + child: const Text("弹窗"), + onPressed: () => openDialog(context), + ), + const Divider(), + ElevatedButton( + child: const Text("底部弹窗出现"), + onPressed: () => openBottomSheet(context), + ), + const Divider(), + ElevatedButton( + child: const Text("底部小弹窗出现"), + onPressed: () => openBottomSheetModal(context), + ), + ], + ), + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example.dart b/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example.dart new file mode 100644 index 0000000000000000000000000000000000000000..6947f6633d8fbc82863f79e394b1d48af8b6d773 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example.dart @@ -0,0 +1,199 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:flutter_svg/svg.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:photo_view/photo_view_gallery.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; +import 'package:test_photo_view/screens/examples/gallery/gallery_example_item.dart'; + +class GalleryExample extends StatefulWidget { + @override + _GalleryExampleState createState() => _GalleryExampleState(); +} + +class _GalleryExampleState extends State { + bool verticalGallery = false; + + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "滚动画廊", + showGoBack: true, + child: Center( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + GalleryExampleItemThumbnail( + galleryExampleItem: galleryItems[0], + onTap: () { + open(context, 0); + }, + ), + GalleryExampleItemThumbnail( + galleryExampleItem: galleryItems[2], + onTap: () { + open(context, 2); + }, + ), + GalleryExampleItemThumbnail( + galleryExampleItem: galleryItems[3], + onTap: () { + open(context, 3); + }, + ), + ], + ), + Row( + mainAxisAlignment: MainAxisAlignment.center, + children: [ + const Text("是否垂直滑动"), + Checkbox( + value: verticalGallery, + onChanged: (value) { + setState(() { + verticalGallery = value!; + }); + }, + ), + ], + ), + ], + ), + ), + ); + } + + void open(BuildContext context, final int index) { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GalleryPhotoViewWrapper( + galleryItems: galleryItems, + backgroundDecoration: const BoxDecoration( + color: Colors.black, + ), + initialIndex: index, + scrollDirection: verticalGallery ? Axis.vertical : Axis.horizontal, + ), + ), + ); + } +} + +class GalleryPhotoViewWrapper extends StatefulWidget { + GalleryPhotoViewWrapper({ + this.loadingBuilder, + this.backgroundDecoration, + this.minScale, + this.maxScale, + this.initialIndex = 0, + required this.galleryItems, + this.scrollDirection = Axis.horizontal, + }) : pageController = PageController(initialPage: initialIndex); + + final LoadingBuilder? loadingBuilder; + final BoxDecoration? backgroundDecoration; + final dynamic minScale; + final dynamic maxScale; + final int initialIndex; + final PageController pageController; + final List galleryItems; + final Axis scrollDirection; + + @override + State createState() { + return _GalleryPhotoViewWrapperState(); + } +} + +class _GalleryPhotoViewWrapperState extends State { + late int currentIndex = widget.initialIndex; + + void onPageChanged(int index) { + setState(() { + currentIndex = index; + }); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Container( + decoration: widget.backgroundDecoration, + constraints: BoxConstraints.expand( + height: MediaQuery.of(context).size.height, + ), + child: Stack( + alignment: Alignment.bottomRight, + children: [ + PhotoViewGallery.builder( + scrollPhysics: const BouncingScrollPhysics(), + builder: _buildItem, + itemCount: widget.galleryItems.length, + loadingBuilder: widget.loadingBuilder, + backgroundDecoration: widget.backgroundDecoration, + pageController: widget.pageController, + onPageChanged: onPageChanged, + scrollDirection: widget.scrollDirection, + ), + Container( + padding: const EdgeInsets.all(20.0), + child: Text( + "Image ${currentIndex + 1}", + style: const TextStyle( + color: Colors.white, + fontSize: 17.0, + decoration: null, + ), + ), + ) + ], + ), + ), + ); + } + + PhotoViewGalleryPageOptions _buildItem(BuildContext context, int index) { + final GalleryExampleItem item = widget.galleryItems[index]; + return item.isSvg + ? PhotoViewGalleryPageOptions.customChild( + child: Container( + width: 300, + height: 300, + child: SvgPicture.asset( + item.resource, + height: 200.0, + ), + ), + childSize: const Size(300, 300), + initialScale: PhotoViewComputedScale.contained, + minScale: PhotoViewComputedScale.contained * (0.5 + index / 10), + maxScale: PhotoViewComputedScale.covered * 4.1, + heroAttributes: PhotoViewHeroAttributes(tag: item.id), + ) + : PhotoViewGalleryPageOptions( + imageProvider: AssetImage(item.resource), + initialScale: PhotoViewComputedScale.contained, + minScale: PhotoViewComputedScale.contained * (0.5 + index / 10), + maxScale: PhotoViewComputedScale.covered * 4.1, + heroAttributes: PhotoViewHeroAttributes(tag: item.id), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example_item.dart b/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example_item.dart new file mode 100644 index 0000000000000000000000000000000000000000..e91a658744a8ebdad78066c8062a76d71530f378 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/gallery/gallery_example_item.dart @@ -0,0 +1,70 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/widgets.dart'; + +class GalleryExampleItem { + GalleryExampleItem({ + required this.id, + required this.resource, + this.isSvg = false, + }); + + final String id; + final String resource; + final bool isSvg; +} + +class GalleryExampleItemThumbnail extends StatelessWidget { + const GalleryExampleItemThumbnail({ + Key? key, + required this.galleryExampleItem, + required this.onTap, + }) : super(key: key); + + final GalleryExampleItem galleryExampleItem; + + final GestureTapCallback onTap; + + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(horizontal: 5.0), + child: GestureDetector( + onTap: onTap, + child: Hero( + tag: galleryExampleItem.id, + child: Image.asset(galleryExampleItem.resource, height: 80.0), + ), + ), + ); + } +} + +List galleryItems = [ + GalleryExampleItem( + id: "tag1", + resource: "assets/gallery1.jpg", + ), + GalleryExampleItem(id: "tag2", resource: "assets/firefox.svg", isSvg: true), + GalleryExampleItem( + id: "tag3", + resource: "assets/gallery2.jpg", + ), + GalleryExampleItem( + id: "tag4", + resource: "assets/gallery3.jpg", + ), +]; diff --git a/ohos/test_photo_view/lib/screens/examples/hero_example.dart b/ohos/test_photo_view/lib/screens/examples/hero_example.dart new file mode 100644 index 0000000000000000000000000000000000000000..10cacc0dffaf1bc5bc7491282a1938e915bcd276 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/hero_example.dart @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class HeroExample extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "Hero 动画\n在加载成功图片之前会有一段替代的东西出现\n可能比较慢", + showGoBack: true, + child: Center( + child: GestureDetector( + onTap: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const HeroPhotoViewRouteWrapper( + imageProvider: NetworkImage( + "http://source.unsplash.com/4900x3600/?camera,paper", + ), + ), + ), + ); + }, + child: Container( + child: Hero( + tag: "someTag", + child: Image.network( + "http://source.unsplash.com/4900x3600/?camera,paper", + width: 350.0, + loadingBuilder: (_, child, chunk) => + chunk != null ? const Text("loading") : child, + ), + ), + ), + ), + ), + ); + } +} + +class HeroPhotoViewRouteWrapper extends StatelessWidget { + const HeroPhotoViewRouteWrapper({ + required this.imageProvider, + this.backgroundDecoration, + this.minScale, + this.maxScale, + }); + + final ImageProvider imageProvider; + final BoxDecoration? backgroundDecoration; + final dynamic minScale; + final dynamic maxScale; + + @override + Widget build(BuildContext context) { + return Container( + constraints: BoxConstraints.expand( + height: MediaQuery.of(context).size.height, + ), + child: PhotoView( + imageProvider: imageProvider, + backgroundDecoration: backgroundDecoration, + minScale: minScale, + maxScale: maxScale, + heroAttributes: const PhotoViewHeroAttributes(tag: "someTag"), + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/inline_examples.dart b/ohos/test_photo_view/lib/screens/examples/inline_examples.dart new file mode 100644 index 0000000000000000000000000000000000000000..8b7094d76deb7c4dd6e24b255d522dfc22099cc9 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/inline_examples.dart @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class InlineExample extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "限制最大大小范围", + showGoBack: true, + child: ListView( + children: [ + Container( + padding: const EdgeInsets.all(20.0), + child: const Text( + "包含上下文中的用法示例", + style: const TextStyle(fontSize: 18.0), + ), + ), + Container( + margin: const EdgeInsets.symmetric( + vertical: 20.0, + horizontal: 20.0, + ), + height: 200.0, + child: ClipRect( + child: PhotoView( + imageProvider: const AssetImage("assets/large-image.jpg"), + maxScale: PhotoViewComputedScale.covered * 2.0, + minScale: PhotoViewComputedScale.contained * 0.8, + initialScale: PhotoViewComputedScale.covered, + ), + ), + ) + ], + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/network_images.dart b/ohos/test_photo_view/lib/screens/examples/network_images.dart new file mode 100644 index 0000000000000000000000000000000000000000..9439e35469bebcfb9648ef3b344c1ae411229c98 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/network_images.dart @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; +import 'package:test_photo_view/screens/common/common_example_wrapper.dart'; +import 'package:test_photo_view/screens/common/example_button.dart'; + +class NetworkExamples extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "网络图像", + showGoBack: true, + child: ListView( + children: [ + ExampleButtonNode( + title: "来自互联网的图像(带有自定义加载程序)", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommonExampleRouteWrapper( + imageProvider: const NetworkImage( + "http://source.unsplash.com/1900x3600/?camera,paper", + ), + loadingBuilder: (context, event) { + if (event == null) { + return const Center( + child: Text("Loading"), + ); + } + + final value = event.cumulativeBytesLoaded / + (event.expectedTotalBytes ?? + event.cumulativeBytesLoaded); + + final percentage = (100 * value).floor(); + return Center( + child: Text("$percentage%"), + ); + }, + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "错误图像", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => const CommonExampleRouteWrapper( + imageProvider: const NetworkImage( + "http://pudim.com.br/sss.jpg", + ), + backgroundDecoration: BoxDecoration( + color: Color(0xffa1a1a1), + ), + ), + ), + ); + }, + ), + ExampleButtonNode( + title: "带有自定义错误屏幕的错误图像", + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommonExampleRouteWrapper( + imageProvider: const NetworkImage( + "http://pudim.com.br/sss.jpg", + ), + errorBuilder: (_, __, ___) { + return Container( + child: Column( + children: [ + Image.asset("assets/neat.gif"), + const Text("well, that went badly"), + ], + ), + ); + }, + ), + ), + ); + }, + ), + ], + ), + ); + } +} diff --git a/ohos/test_photo_view/lib/screens/examples/rotation_examples.dart b/ohos/test_photo_view/lib/screens/examples/rotation_examples.dart new file mode 100644 index 0000000000000000000000000000000000000000..5973f8b3f1e390027afd3c53e7c64ee9de90e303 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/examples/rotation_examples.dart @@ -0,0 +1,127 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:math' as math; + +import 'package:flutter/material.dart'; +import 'package:photo_view/photo_view.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; + +class GestureRotationExample extends StatelessWidget { + @override + Widget build(BuildContext context) { + return ExampleAppBarLayout( + title: "旋转手势", + showGoBack: true, + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(20.0), + child: const Text( + "使用选项enableRotation的示例,只需捏住旋转", + style: const TextStyle(fontSize: 18.0), + ), + ), + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(vertical: 20.0), + height: 300.0, + child: ClipRect( + child: PhotoView( + imageProvider: const AssetImage("assets/large-image.jpg"), + maxScale: PhotoViewComputedScale.covered, + initialScale: PhotoViewComputedScale.contained * 0.8, + enableRotation: true, + ), + ), + ), + ), + ], + ), + ); + } +} + +class ProgrammaticRotationExample extends StatefulWidget { + @override + _ProgrammaticRotationExampleState createState() => + _ProgrammaticRotationExampleState(); +} + +class _ProgrammaticRotationExampleState + extends State { + final PhotoViewController _controller = PhotoViewController(); + var _quarterTurns = 0; + + @override + void dispose() { + _controller.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const ExampleAppBar( + title: "旋转", + showGoBack: true, + ), + Expanded( + child: Column( + children: [ + Container( + padding: const EdgeInsets.all(20.0), + child: const Text( + "示例无手动旋转,点击按钮旋转", + style: const TextStyle(fontSize: 18.0), + ), + ), + Expanded( + child: Container( + margin: const EdgeInsets.symmetric(vertical: 20.0), + height: 300.0, + child: ClipRect( + child: PhotoView( + controller: _controller, + imageProvider: + const AssetImage("assets/large-image.jpg"), + maxScale: PhotoViewComputedScale.covered, + initialScale: PhotoViewComputedScale.contained * 0.8, + enableRotation: false, + ), + ), + ), + ), + ], + ), + ) + ], + ), + floatingActionButton: FloatingActionButton( + child: const Icon(Icons.rotate_right), + onPressed: _rotateRight90Degrees, + ), + ); + } + + void _rotateRight90Degrees() { + // Set the rotation to either 0, 90, 180 or 270 degrees (value is in radians) + _quarterTurns = _quarterTurns == 3 ? 0 : _quarterTurns + 1; + _controller.rotation = math.pi / 2 * _quarterTurns; + } +} diff --git a/ohos/test_photo_view/lib/screens/home_screen.dart b/ohos/test_photo_view/lib/screens/home_screen.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fcb0f48a4c20b9b1d6bc1bb06afb872f4d76ba7 --- /dev/null +++ b/ohos/test_photo_view/lib/screens/home_screen.dart @@ -0,0 +1,191 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_photo_view/screens/common/app_bar.dart'; +import 'package:test_photo_view/screens/examples/common_use_cases_examples.dart'; +import 'package:test_photo_view/screens/examples/controller_example.dart'; +import 'package:test_photo_view/screens/examples/custom_child_examples.dart'; +import 'package:test_photo_view/screens/examples/dialog_example.dart'; +import 'package:test_photo_view/screens/examples/gallery/gallery_example.dart'; +import 'package:test_photo_view/screens/examples/hero_example.dart'; +import 'package:test_photo_view/screens/examples/inline_examples.dart'; +import 'package:test_photo_view/screens/examples/rotation_examples.dart'; + +import 'examples/network_images.dart'; + +class HomeScreen extends StatelessWidget { + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: const Color.fromARGB(255, 255, 255, 255), + body: Column( + crossAxisAlignment: CrossAxisAlignment.stretch, + children: [ + const ExampleAppBar(title: "Photo View"), + Container( + padding: const EdgeInsets.all(20.0), + child: const Text( + "请参阅下面一些最常见的照片视图用例示例", + style: const TextStyle(fontSize: 18.0), + ), + ), + Expanded( + child: ListView( + children: [ + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => CommonUseCasesExamples(), + ), + ); + }, + text: "常见用例", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => GalleryExample(), + ), + ); + }, + text: "滚动画廊", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => HeroExample(), + ), + ); + }, + text: "Hero 动画", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => NetworkExamples(), + ), + ); + }, + text: "网络图像", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ControllerExample(), + ), + ); + }, + text: "Controller", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => InlineExample(), + ), + ); + }, + text: "限制最大大小范围", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (_) => CustomChildExample(), + ), + ); + }, + text: "一个显示可缩放子对象的小部件", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => DialogExample(), + ), + ); + }, + text: "集成到对话框", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => GestureRotationExample(), + ), + ); + }, + text: "旋转手势", + ), + _buildItem( + context, + onPressed: () { + Navigator.push( + context, + MaterialPageRoute( + builder: (context) => ProgrammaticRotationExample(), + ), + ); + }, + text: "旋转程序", + ), + ], + ), + ), + ], + ), + ); + } + + Widget _buildItem(context, + {required String text, required VoidCallback onPressed}) { + return TextButton( + style: ButtonStyle( + padding: MaterialStateProperty.all( + const EdgeInsets.symmetric(vertical: 25.0, horizontal: 20.0), + ), + ), + child: Text( + text, + style: const TextStyle(fontSize: 18.0, fontWeight: FontWeight.w700), + ), + onPressed: onPressed, + ); + } +} diff --git a/ohos/test_photo_view/ohos/.gitignore b/ohos/test_photo_view/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_photo_view/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/AppScope/app.json5 b/ohos/test_photo_view/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..42d00f658954cef0db0e8ec11c489143137fadb2 --- /dev/null +++ b/ohos/test_photo_view/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_photo_view", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_photo_view/ohos/AppScope/resources/base/element/string.json b/ohos/test_photo_view/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f9235a3e98068b9a03b203856c7168fc75c4c68a --- /dev/null +++ b/ohos/test_photo_view/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_photo_view" + } + ] +} diff --git a/ohos/test_photo_view/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_photo_view/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_photo_view/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_photo_view/ohos/build-profile.json5 b/ohos/test_photo_view/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bb72b1aaaddb98ad97e17441d3db6b95bdbc4cf --- /dev/null +++ b/ohos/test_photo_view/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_photo_view.cer", + "storePassword": "0000001BA1F2D6D20E3F0AC41FAB660CD4310C4369EB4B5109BF0A6BA8065CD1F203E5D6FD1C5563C8FB0D", + "keyAlias": "debugKey", + "keyPassword": "0000001B82CF3F254D57A3625643B5215F547D17854A02F05B1CFC93DE4E3CAE08D6CA4C6C4687308805EE", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_photo_view.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_photo_view.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_photo_view/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_photo_view/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_photo_view/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_photo_view/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_photo_view/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_photo_view/ohos/dependencies/rollup.tgz b/ohos/test_photo_view/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_photo_view/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_photo_view/ohos/dta/icudtl.dat b/ohos/test_photo_view/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_photo_view/ohos/dta/icudtl.dat differ diff --git a/ohos/test_photo_view/ohos/entry/.gitignore b/ohos/test_photo_view/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/build-profile.json5 b/ohos/test_photo_view/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/hvigorfile.ts b/ohos/test_photo_view/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_photo_view/ohos/entry/oh-package.json5 b/ohos/test_photo_view/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_photo_view/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_photo_view/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_photo_view/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_photo_view/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/module.json5 b/ohos/test_photo_view/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_photo_view/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_photo_view/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_photo_view/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..a7db205d1b1fdb2e7ee9d281bcad07a2105a3138 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{"assets/firefox.svg":["assets/firefox.svg"],"assets/fonts/ptasans-bold.ttf":["assets/fonts/ptasans-bold.ttf"],"assets/fonts/ptasans-regular.ttf":["assets/fonts/ptasans-regular.ttf"],"assets/gallery1.jpg":["assets/gallery1.jpg"],"assets/gallery2.jpg":["assets/gallery2.jpg"],"assets/gallery3.jpg":["assets/gallery3.jpg"],"assets/large-image.jpg":["assets/large-image.jpg"],"assets/neat.gif":["assets/neat.gif"],"assets/small-image.jpg":["assets/small-image.jpg"]} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..103682a9b97dd992327c4210eb9579a67deec318 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"PTSans","fonts":[{"asset":"assets/fonts/ptasans-regular.ttf"},{"weight":700,"asset":"assets/fonts/ptasans-bold.ttf"}]}] \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..f8f37f758e99f2bde7302f718836f094c57ff899 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/firefox.svg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/firefox.svg new file mode 100644 index 0000000000000000000000000000000000000000..87caae6a7913afafb1adcaa9147149a6d7be6ad6 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/firefox.svg @@ -0,0 +1,139 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + firefox-logo + + + + + + + + + + + + + + + + + diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-bold.ttf b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-bold.ttf new file mode 100644 index 0000000000000000000000000000000000000000..cc597adad9da682d3acf93276acbcb33af326d1c Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-bold.ttf differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-regular.ttf b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-regular.ttf new file mode 100644 index 0000000000000000000000000000000000000000..c1249393df577f661863948f3d128dd98fea485b Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/fonts/ptasans-regular.ttf differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery1.jpg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..15fc8ceabb0d87e47bde07029ee1970e3e369aaf Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery1.jpg differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery2.jpg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery2.jpg new file mode 100644 index 0000000000000000000000000000000000000000..766398d06568e9a8f3f60ab31f4af31b5da83435 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery2.jpg differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery3.jpg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery3.jpg new file mode 100644 index 0000000000000000000000000000000000000000..0b3e67e7ba7452330821736efd8bddace84ae1df Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/gallery3.jpg differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/large-image.jpg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/large-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..67c1bc9228fec86c060b4f851eb8403ed784dfec Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/large-image.jpg differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/neat.gif b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/neat.gif new file mode 100644 index 0000000000000000000000000000000000000000..438b1109aa146ad0504252c15ddb7277099d430a Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/neat.gif differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/small-image.jpg b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/small-image.jpg new file mode 100644 index 0000000000000000000000000000000000000000..9ae2739442fb371e47e26d9f4451f53dc1514a01 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/assets/small-image.jpg differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..ba73bffc68a6d9db9f01d390e0f38fae407be2da Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_photo_view/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_photo_view/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/module.json5 b/ohos/test_photo_view/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_photo_view/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_photo_view/ohos/har/flutter_embedding.har b/ohos/test_photo_view/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_photo_view/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_photo_view/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.10 b/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.9 b/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_photo_view/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_photo_view/ohos/har/libflutter.so.debug.10 b/ohos/test_photo_view/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_photo_view/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_photo_view/ohos/har/libflutter.so.release.10 b/ohos/test_photo_view/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_photo_view/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_photo_view/ohos/hvigor/hvigor-config.json5 b/ohos/test_photo_view/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_photo_view/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_photo_view/ohos/hvigor/hvigor-wrapper.js b/ohos/test_photo_view/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_photo_view/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/hvigorfile.ts b/ohos/test_photo_view/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_photo_view/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/hvigorw b/ohos/test_photo_view/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_photo_view/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_photo_view/ohos/hvigorw.bat b/ohos/test_photo_view/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_photo_view/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_photo_view/ohos/oh-package-lock.json5 b/ohos/test_photo_view/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_photo_view/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_photo_view/ohos/oh-package.json5 b/ohos/test_photo_view/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_photo_view/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_photo_view/pubspec.yaml b/ohos/test_photo_view/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..e3e83fd43552deda6ea2f5fd4c239075b10bc975 --- /dev/null +++ b/ohos/test_photo_view/pubspec.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_photo_view +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + photo_view: 0.14.0 + flutter_svg: 2.0.5 +flutter: + uses-material-design: true + assets: + - assets/neat.gif + - assets/large-image.jpg + - assets/small-image.jpg + - assets/gallery1.jpg + - assets/gallery2.jpg + - assets/gallery3.jpg + - assets/firefox.svg + + fonts: + - family: PTSans + fonts: + - asset: assets/fonts/ptasans-regular.ttf + - asset: assets/fonts/ptasans-bold.ttf + weight: 700 \ No newline at end of file diff --git a/ohos/test_quiver/.gitignore b/ohos/test_quiver/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_quiver/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_quiver/.metadata b/ohos/test_quiver/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_quiver/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_quiver/README.md b/ohos/test_quiver/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_quiver/analysis_options.yaml b/ohos/test_quiver/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_quiver/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_quiver/lib/common/base_page.dart b/ohos/test_quiver/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_quiver/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_quiver/lib/common/item_widget.dart b/ohos/test_quiver/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_quiver/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_quiver/lib/common/main_item_widget.dart b/ohos/test_quiver/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_quiver/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_quiver/lib/common/test_model_app.dart b/ohos/test_quiver/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_quiver/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_quiver/lib/common/test_page.dart b/ohos/test_quiver/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_quiver/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_quiver/lib/common/test_route.dart b/ohos/test_quiver/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_quiver/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_quiver/lib/main.dart b/ohos/test_quiver/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..e7e1416d52736dd3bd43f8e9aa6fe1908bae0293 --- /dev/null +++ b/ohos/test_quiver/lib/main.dart @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; +import 'package:test_quiver/src/async/collect_test.dart'; +import 'package:test_quiver/src/async/concat_test.dart'; +import 'package:test_quiver/src/async/countdown_timer_test.dart'; +import 'package:test_quiver/src/async/enumerate_test.dart'; +import 'package:test_quiver/src/async/future_stream_test.dart'; +import 'package:test_quiver/src/async/metronome_test.dart'; +import 'package:test_quiver/src/async/stream_buffer_test.dart'; +import 'package:test_quiver/src/async/stream_router_test.dart'; +import 'package:test_quiver/src/async/string_test.dart'; +import 'package:test_quiver/src/cache/map_cache_test.dart'; +import 'package:test_quiver/src/check_test.dart'; +import 'package:test_quiver/src/collection/bimap_test.dart'; +import 'package:test_quiver/src/collection/delegates/iterable_test.dart'; +import 'package:test_quiver/src/collection/delegates/list_test.dart'; +import 'package:test_quiver/src/collection/delegates/map_test.dart'; +import 'package:test_quiver/src/collection/delegates/queue_test.dart'; +import 'package:test_quiver/src/collection/delegates/set_test.dart'; +import 'package:test_quiver/src/collection/lru_map_test.dart'; +import 'package:test_quiver/src/collection/multimap_test.dart'; +import 'package:test_quiver/src/collection/treeset_test.dart'; +import 'package:test_quiver/src/collection/utils_test.dart'; +import 'package:test_quiver/src/core/hash_test.dart'; +import 'package:test_quiver/src/core/optional_test.dart'; +import 'package:test_quiver/src/core/utils_test.dart'; +import 'package:test_quiver/src/iterables/concat_test.dart'; +import 'package:test_quiver/src/iterables/count_test.dart'; +import 'package:test_quiver/src/iterables/cycle_test.dart'; +import 'package:test_quiver/src/iterables/enumerate_test.dart'; +import 'package:test_quiver/src/iterables/generating_iterable_test.dart'; +import 'package:test_quiver/src/iterables/infinite_iterable_test.dart'; +import 'package:test_quiver/src/iterables/merge_test.dart'; +import 'package:test_quiver/src/iterables/min_max_test.dart'; +import 'package:test_quiver/src/iterables/partition_test.dart'; +import 'package:test_quiver/src/iterables/range_test.dart'; +import 'package:test_quiver/src/iterables/zip_test.dart'; +import 'package:test_quiver/src/pattern/glob_test.dart'; +import 'package:test_quiver/src/pattern/pattern_test.dart'; +import 'package:test_quiver/src/strings_test.dart'; +import 'package:test_quiver/src/testing/async/fake_async_test.dart'; +import 'package:test_quiver/src/testing/equality/equality_test.dart'; +import 'package:test_quiver/src/time/clock_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + final app = [ + MainItem('collect_test', CollectTestPage('collect_test')), + MainItem('concat_test' ,ConcatTestPage('concat_test')), + MainItem('countdown_timer_test' ,CountDownTimerTestPage('countdown_timer_test')), + MainItem('enumerate_test' ,EnumerateTestPage('enumerate_test')), + MainItem('future_stream_test' ,FutureStreamTestPage('future_stream_test')), + MainItem('metronome_test' ,MetronomeTestPage('metronome_test')), + MainItem('stream_buffer_test' ,StreamBufferTestPage('stream_buffer_test')), + MainItem('stream_router_test' ,StreamRouterTestPage('stream_router_test')), + MainItem('string_test' ,StringTestPage('string_test')), + MainItem('map_cache_test' ,MapCacheTestPage('map_cache_test')), + MainItem('iterable_test' ,IterableTestPage('iterable_test')), + MainItem('list_test' ,ListTestPage('list_test')), + MainItem('map_test' ,MapTestPage('map_test')), + MainItem('queue_test' ,QueueTestPage('queue_test')), + MainItem('set_test' ,SetTestPage('set_test')), + MainItem('bimap_test' ,BimapTestPage('bimap_test')), + MainItem('lru_map_test' ,LruMapTestPage('lru_map_test')), + MainItem('multimap_test' ,MultimapTestPage('multimap_test')), + MainItem('treeset_test' ,TreeSetTestPage('treeset_test')), + MainItem('utils_test' ,UtilsTestPage('utils_test')), + MainItem('hash_test' ,HashTestPage('hash_test')), + MainItem('optional_test' ,OptionalTestPage('optional_test')), + MainItem('collection_utils_test' ,CollectionUtilsTestPage('collection_utils_test')), + MainItem('iterables_concat_test' ,IterablesConcatTestPage('iterables_concat_test')), + MainItem('count_test' ,CountTestPage('count_test')), + MainItem('cycle_test' ,CycleTestPage('cycle_test')), + MainItem('iterables_enumerate_test' ,IterablesEnumerateTestPage('iterables_enumerate_test')), + MainItem('generating_iterable_test' ,GeneratingIterableTestPage('generating_iterable_test')), + MainItem('infinite_iterable_test' ,InfiniteIterablePage('infinite_iterable_test')), + MainItem('merge_test' ,MergeTestPage('merge_test')), + MainItem('min_max_test' ,MinMaxTestPage('min_max_test')), + MainItem('partition_test' ,PartitionTestPage('partition_test')), + MainItem('range_test' ,RangeTestPage('range_test')), + MainItem('zip_test' ,ZipTestPage('zip_test')), + MainItem('glob_test' ,GlobTestPage('glob_test')), + MainItem('pattern_test' ,PatternTestPage('pattern_test')), + MainItem('fake_async_test' ,FakeAsyncTestPage('fake_async_test')), + MainItem('equality_test' ,EqualityTestPage('equality_test')), + MainItem('clock_test' ,ClockTestPage('clock_test')), + MainItem('check_test' ,CheckTestPage('check_test')), + MainItem('strings_test' ,StringsTestPage('strings_test')), + ]; + + runApp(TestModelApp(appName: 'quiver', data: app)); +} diff --git a/ohos/test_quiver/lib/src/async/collect_test.dart b/ohos/test_quiver/lib/src/async/collect_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1b0adccfbb833644d235f987bfa8ffa260b7d89b --- /dev/null +++ b/ohos/test_quiver/lib/src/async/collect_test.dart @@ -0,0 +1,73 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.collect_test; + +import 'dart:async'; +import 'dart:math'; + +import 'package:quiver/src/async/collect.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CollectTestPage extends TestPage { + CollectTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('collect', () { + test('不应该产生任何事件', + () => collect([]).toList().then((events) => events.isEmpty)); + + test('应按输入顺序为将来的完成生成事件', () { + var futures = Iterable.generate( + 5, (int i) => i.isEven ? Future.value(i) : Future.error(i)); + var events = []; + var done = Completer>(); + + collect(futures).listen(events.add, + onError: (i) { + events.add('e$i'); + }, + onDone: () => done.complete([])); + return Future.wait(futures).catchError((_) => done.future).then((_) { + expect(events, [0, 'e1', 2, 'e3', 4]); + }); + }); + + test('发送上一个将来的事件', () { + var eventCount = 0; + var maxParallel = 0; + var currentParallel = 0; + var done = Completer(); + var futures = Iterable.generate(3, (_) { + maxParallel = max(++currentParallel, maxParallel); + return Future.value(); + }); + + var collected = collect(futures); + + void decrementParallel(_) { + eventCount++; + currentParallel--; + } + + collected.listen(decrementParallel, + onError: decrementParallel, onDone: done.complete); + return done.future.then((_) { + expect(maxParallel, 1); + expect(eventCount, 3); + }); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/async/concat_test.dart b/ohos/test_quiver/lib/src/async/concat_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a4918a1eef29b976dea5a5a6dd62f2d5494b8460 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/concat_test.dart @@ -0,0 +1,112 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +library quiver.async.concat_test; + +import 'dart:async'; + +import 'package:quiver/src/async/concat.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class ConcatTestPage extends TestPage { + ConcatTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('concat', () { + test('没有事件', + () => concat([]).toList().then((events) => events.isEmpty)); + + test('应回显单个流的事件', () { + var controller = StreamController(); + var concatenated = concat([controller.stream]); + var expectation = concatenated.toList().then((e) { + expect(e, ['a', 'b', 'c']); + }); + ['a', 'b', 'c'].forEach(controller.add); + return Future.wait([controller.close(), expectation]); + }); + + test('应处理空流', () { + var concatenated = concat([Stream.fromIterable([])]); + return concatenated.toList().then((e) { + expect(e, []); + }); + }); + + test('应连接流数据事件', () { + var controller1 = StreamController(); + var controller2 = StreamController(); + var concatenated = concat([controller1.stream, controller2.stream]); + var expectation = concatenated.toList().then((e) { + expect(e, ['a', 'b', 'c', 'd', 'e', 'f']); + }); + ['a', 'b', 'c'].forEach(controller1.add); + ['d', 'e', 'f'].forEach(controller2.add); + return Future.wait( + [controller1.close(), controller2.close(), expectation]); + }); + + test('应连接流错误事件', () { + var controller1 = StreamController(); + var controller2 = StreamController(); + var concatenated = concat([controller1.stream, controller2.stream]); + var errors = []; + concatenated.listen(null, onError: errors.add); + ['e1', 'e2'].forEach(controller1.addError); + ['e3', 'e4'].forEach(controller2.addError); + return Future.wait([controller1.close(), controller2.close()]).then((_) { + expect(errors, ['e1', 'e2', 'e3', 'e4']); + }); + }); + + test('应将暂停、继续和取消转发到当前流', () { + var wasPaused = false, wasResumed = false, wasCanceled = false; + var controller = StreamController( + onPause: () => wasPaused = true, + onResume: () => wasResumed = true, + onCancel: () { + wasCanceled = true; + }); + var concatenated = concat([controller.stream]); + var subscription = concatenated.listen(null); + controller.add('a'); + return Future.value() + .then((_) => subscription.pause()) + .then((_) => subscription.resume()) + + // Give resume a chance to take effect. + .then((_) => controller.add('b')) + .then((_) => Future(subscription.cancel)) + .then((_) { + expect(wasPaused, true); + expect(wasResumed, true); + expect(wasCanceled, true); + }).then((_) => controller.close()); + }); + + test('应该转发错误并停止', () { + var data = [], errors = []; + var badIteration = + ['e', 'this should not get thrown'].map((message) => throw message); + var concatenated = concat(badIteration); + var completer = Completer(); + concatenated.listen(data.add, + onError: errors.add, onDone: completer.complete); + return completer.future.then((_) { + expect(data, []); + expect(errors, ['e']); + }); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/countdown_timer_test.dart b/ohos/test_quiver/lib/src/async/countdown_timer_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..68ed8e568bc3fb85e04e934116da22c335abfebb --- /dev/null +++ b/ohos/test_quiver/lib/src/async/countdown_timer_test.dart @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.countdown_timer_test; + +import 'package:quiver/src/async/countdown_timer.dart'; +import 'package:quiver/testing/async.dart'; +import 'package:quiver/testing/time.dart'; +import 'package:quiver/time.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CountDownTimerTestPage extends TestPage { + CountDownTimerTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('CountdownTimer', () { + test('倒计时', () { + FakeAsync().run((FakeAsync async) async { + var clock = async.getClock(DateTime.fromMillisecondsSinceEpoch(0)); + var stopwatch = FakeStopwatch( + () => 1000 * clock.now().millisecondsSinceEpoch, 1000000); + + var timings = CountdownTimer(const Duration(milliseconds: 500), + const Duration(milliseconds: 100), + stopwatch: stopwatch) + .map((c) => c.remaining.inMilliseconds); + + List result = await timings.toList(); + async.elapse(aMillisecond * 500); + expect(result, [400, 300, 200, 100, 0]); + }); + }); + + test('设置初始化值', () { + var timer = CountdownTimer( + const Duration(milliseconds: 321), const Duration(milliseconds: 123)); + expect(timer.increment, const Duration(milliseconds: 123)); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/enumerate_test.dart b/ohos/test_quiver/lib/src/async/enumerate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b71c2813d9354198ee4834ebd0b23c0ea3b42331 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/enumerate_test.dart @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.enumerate_test; + +import 'dart:async'; + +import 'package:quiver/src/async/enumerate.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class EnumerateTestPage extends TestPage { + EnumerateTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('Enumerate', () { + test('应为其参数添加索引', () { + var controller = StreamController(); + var enumerated = enumerate(controller.stream); + var expectation = enumerated.toList().then((e) { + expect(e.map((v) => v.index), [0, 1, 2]); + expect(e.map((v) => v.value), ['a', 'b', 'c']); + }); + ['a', 'b', 'c'].forEach(controller.add); + return Future.wait([controller.close(), expectation]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/future_stream_test.dart b/ohos/test_quiver/lib/src/async/future_stream_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..0205c30bba4717a02132bd84c3dcbbb13b0ba390 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/future_stream_test.dart @@ -0,0 +1,85 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.future_stream_test; + +import 'dart:async'; + +import 'package:quiver/src/async/future_stream.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class FutureStreamTestPage extends TestPage { + FutureStreamTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('FutureStream', () { + test('应该转发事件', () { + var completer = Completer>(); + var controller = StreamController(); + var futureStream = FutureStream(completer.future); + + var done = futureStream.first.then((s) { + expect(s, 'hello'); + }); + + completer.complete(controller.stream); + controller.add('hello'); + + return done; + }); + + test('stream需要被关闭', () { + var completer = Completer>(); + var controller = StreamController(); + var futureStream = FutureStream(completer.future); + + var testCompleter = Completer(); + + futureStream.listen((_) {}, onDone: () { + // pass + testCompleter.complete(); + }); + + completer.complete(controller.stream); + controller.close(); + + return testCompleter.future; + }); + + test('应转发错误', () { + var completer = Completer>(); + var controller = StreamController(); + var futureStream = FutureStream(completer.future); + + var testCompleter = Completer(); + + futureStream.listen((_) {}, onError: (e) { + expect(e, 'error'); + testCompleter.complete(); + }); + + completer.complete(controller.stream); + controller.addError('error'); + + return testCompleter.future; + }); + + test('应该广播', () { + var completer = Completer>(); + var futureStream = FutureStream(completer.future, broadcast: true); + expect(futureStream.isBroadcast, true); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/metronome_test.dart b/ohos/test_quiver/lib/src/async/metronome_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..bc240be1ac6d8e7a36c5a22c8e300efe45883766 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/metronome_test.dart @@ -0,0 +1,199 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.time.clock_test; + +import 'package:quiver/src/async/metronome.dart'; +import 'package:quiver/testing/async.dart'; +import 'package:quiver/time.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class MetronomeTestPage extends TestPage { + MetronomeTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('Metronome', () { + test('按预期时间交付事件', () { + FakeAsync().run((async) { + int callbacks = 0; + + // Initialize metronome with start time. + DateTime lastTime = DateTime.parse('2014-05-05 20:00:30'); + var sub = Metronome.epoch(aMinute, clock: async.getClock(lastTime)) + .listen((d) { + callbacks++; + lastTime = d; + }); + expect(callbacks, 0,); + async.elapse(aSecond * 15); + expect(callbacks, 0); + async.elapse(aSecond * 15); + expect(callbacks, 1); + expect(lastTime, DateTime.parse('2014-05-05 20:01:00') + ); + async.elapse(aMinute * 1); + expect(callbacks, 2); + expect(lastTime, DateTime.parse('2014-05-05 20:02:00') + ); + sub.cancel(); + async.elapse(aMinute * 2); + expect(callbacks, 2); + }); + }); + + test('可以重新收听', () { + FakeAsync().run((async) { + int callbacks = 0; + var clock = Metronome.epoch(aMinute, + clock: async.getClock(DateTime.parse('2014-05-05 20:00:30'))); + var sub = clock.listen((d) { + callbacks++; + }); + async.elapse(aMinute); + expect(callbacks, 1); + sub.cancel(); + async.elapse(aMinute); + expect(callbacks, 1); + sub = clock.listen((d) { + callbacks++; + }); + async.elapse(aMinute); + expect(callbacks, 2); + }); + }); + + test('支持多个侦听器加入和离开', () { + FakeAsync().run((async) { + List callbacks = [0, 0]; + var clock = Metronome.epoch(aMinute, + clock: async.getClock(DateTime.parse('2014-05-05 20:00:30'))); + List subs = [ + clock.listen((d) { + callbacks[0]++; + }), + clock.listen((d) { + callbacks[1]++; + }) + ]; + + async.elapse(aMinute); + expect(callbacks, [1, 1]); + subs[0].cancel(); + async.elapse(aMinute); + expect(callbacks, [1, 2]); + }); + }); + + test('随时关闭', () { + FakeAsync().run((async) { + List times = []; + DateTime start = DateTime.parse('2014-05-05 20:06:00'); + Clock clock = async.getClock(start); + Metronome.periodic(aMinute * 10, + clock: clock, anchor: clock.minutesAgo(59)) + .listen((d) { + times.add(d); + }); + async.elapse(anHour); + expect(times, [ + DateTime.parse('2014-05-05 20:07:00'), + DateTime.parse('2014-05-05 20:17:00'), + DateTime.parse('2014-05-05 20:27:00'), + DateTime.parse('2014-05-05 20:37:00'), + DateTime.parse('2014-05-05 20:47:00'), + DateTime.parse('2014-05-05 20:57:00'), + ]); + }); + }); + + test('可以在一段时间后暂停', () { + FakeAsync().run((async) { + List times = []; + DateTime start = DateTime.parse('2014-05-05 20:06:00'); + Clock clock = async.getClock(start); + Metronome.periodic(aMinute * 10, + clock: clock, anchor: clock.minutesFromNow(61)) + .listen((d) { + times.add(d); + }); + async.elapse(anHour); + expect(times, [ + DateTime.parse('2014-05-05 20:07:00'), + DateTime.parse('2014-05-05 20:17:00'), + DateTime.parse('2014-05-05 20:27:00'), + DateTime.parse('2014-05-05 20:37:00'), + DateTime.parse('2014-05-05 20:47:00'), + DateTime.parse('2014-05-05 20:57:00'), + ]); + }); + }); + + test('周期性计时器', () { + FakeAsync().run((async) { + List times = []; + DateTime start = DateTime.parse('2014-05-05 20:06:00.004'); + Metronome.periodic(aMillisecond * 100, + clock: async.getClock(start), anchor: start) + .listen((d) { + times.add(d); + }); + async.elapse(aMillisecond * 304); + expect(times, [ + DateTime.parse('2014-05-05 20:06:00.104'), + DateTime.parse('2014-05-05 20:06:00.204'), + DateTime.parse('2014-05-05 20:06:00.304'), + ]); + }); + }); + + test('重新同步', () { + FakeAsync().run((async) { + List times = []; + DateTime start = DateTime.parse('2014-05-05 20:06:00.004'); + Metronome.periodic(aMillisecond * 100, + clock: async.getClock(start), anchor: start) + .listen((d) { + times.add(d); + async.elapseBlocking(const Duration(milliseconds: 80)); + }); + async.elapse(aMillisecond * 304); + expect(times, [ + DateTime.parse('2014-05-05 20:06:00.104'), + DateTime.parse('2014-05-05 20:06:00.204'), + DateTime.parse('2014-05-05 20:06:00.304'), + ]); + }); + }); + + test('超时重连', () { + FakeAsync().run((async) { + List times = []; + DateTime start = DateTime.parse('2014-05-05 20:06:00.004'); + Metronome.periodic(aMillisecond * 100, + clock: async.getClock(start), anchor: start) + .listen((d) { + times.add(d); + async.elapseBlocking(const Duration(milliseconds: 105)); + }); + async.elapse(aMillisecond * 504); + expect(times, [ + DateTime.parse('2014-05-05 20:06:00.104'), + DateTime.parse('2014-05-05 20:06:00.304'), + DateTime.parse('2014-05-05 20:06:00.504'), + ]); + }); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/stream_buffer_test.dart b/ohos/test_quiver/lib/src/async/stream_buffer_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..cfa986193382625376419ecb0bffcb8e85a83916 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/stream_buffer_test.dart @@ -0,0 +1,117 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.stream_buffer_test; + +import 'package:quiver/src/async/stream_buffer.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class StreamBufferTestPage extends TestPage { + StreamBufferTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('StreamBuffer', () { + test('有序返回数据', () { + StreamBuffer buf = StreamBuffer(); + Stream.fromIterable([ + [1], + [2, 3, 4], + [5, 6, 7, 8] + ]).pipe(buf); + return Future.wait([buf.read(2), buf.read(4), buf.read(2)]).then((vals) { + expect(vals[0], [1, 2]); + expect(vals[1], [3, 4, 5, 6]); + expect(vals[2], [7, 8]); + }).then((_) { + buf.close(); + }); + }); + + test('可以收听到流的暂停', () { + StreamBuffer buf = StreamBuffer()..limit = 2; + Stream.fromIterable([ + [1], + [2], + [3], + [4] + ]).pipe(buf); + return buf.read(2).then((val) { + expect(val, [1, 2]); + }).then((_) { + return buf.read(2); + }).then((val) { + expect(val, [3, 4]); + }); + }); + + test('大量获取数据时抛出异常', () { + StreamBuffer buf = StreamBuffer()..limit = 1; + Stream.fromIterable([ + [1], + [2] + ]).pipe(buf); + try { + buf.read(2); + } catch (e) { + e; + return; + } + fail('error not thrown when reading more data than buffer limit'); + }); + + test('允许重连流', () { + StreamBuffer buf = StreamBuffer(); + Stream.fromIterable([ + [1, 2] + ]).pipe(buf).then((_) { + return Stream.fromIterable([ + [3, 4] + ]).pipe(buf); + }); + return Future.wait([buf.read(1), buf.read(2), buf.read(1)]).then((vals) { + expect(vals[0], [1]); + expect(vals[1], [2, 3]); + expect(vals[2], [4]); + }); + }); + + test('溢出错误', () async { + StreamBuffer buf = StreamBuffer(throwOnError: true); + Future> futureBytes = buf.read(4); + Stream.fromIterable([ + [1, 2, 3] + ]).pipe(buf); + try { + List bytes = await futureBytes; + fail('should not have gotten bytes: $bytes'); + } catch (e) { + expect(e is UnderflowError, true); + } + }); + + test('接受多个流', () async { + StreamBuffer buf = StreamBuffer(); + Stream.fromIterable([ + [1] + ]).pipe(buf); + Stream.fromIterable([ + [2, 3, 4, 5] + ]).pipe(buf); + final vals = await buf.read(4); + expect(vals, [2, 3, 4, 5]); + buf.close(); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/stream_router_test.dart b/ohos/test_quiver/lib/src/async/stream_router_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b6656d5cc3e25cd91ca5320563c08d95b58df0f8 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/stream_router_test.dart @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.async.stream_router_test; + +import 'dart:async'; + +import 'package:quiver/src/async/stream_router.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class StreamRouterTestPage extends TestPage { + StreamRouterTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('StreamRouter', () { + test('应将事件路由到正确的流', () { + var controller = StreamController(); + StreamRouter(controller.stream) + ..route((e) => e == 'foo').listen((e) { + expect(e, 'foo'); + }) + ..route((e) => e == 'bar').listen((e) { + fail('wrong stream'); + }) + ..route((e) => e == 'foo').listen((e) { + fail('wrong stream'); + }) + ..defaultStream.listen((e) { + fail('wrong stream'); + }); + controller.add('foo'); + return controller.close(); + }); + + test('应将不匹配谓词的事件发送到默认流', () { + var controller = StreamController(); + StreamRouter(controller.stream) + ..route((e) => e == 'foo').listen((e) { + fail('wrong stream'); + }) + ..route((e) => e == 'bar').listen((e) { + fail('wrong stream'); + }) + ..defaultStream.listen((e) { + expect(e, 'baz'); + }); + controller.add('baz'); + return controller.close(); + }); + + test('应关闭子流', () { + var controller = StreamController(sync: true); + var router = StreamRouter(controller.stream); + // toList() will only complete when the child streams are closed + var future = Future.wait([ + router.route((e) => e % 2 == 0).toList(), + router.route((e) => e % 2 == 1).toList(), + ]).then((l) { + expect(l, [ + [4], + [5] + ]); + }); + controller + ..add(4) + ..add(5); + router.close(); + return future; + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/async/string_test.dart b/ohos/test_quiver/lib/src/async/string_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b2482508c85d6781bbb6241152e80f7cb422a363 --- /dev/null +++ b/ohos/test_quiver/lib/src/async/string_test.dart @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:convert' show latin1, utf8; + +import 'package:quiver/src/async/string.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class StringTestPage extends TestPage { + StringTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('byteStreamToString', () { + test('默认情况下应解码UTF8文本', () { + var string = '箙、靫'; + var encoded = utf8.encoder.convert(string); + var data = [encoded.sublist(0, 3), encoded.sublist(3)]; + var stream = Stream>.fromIterable(data); + byteStreamToString(stream).then((decoded) { + expect(decoded, string); + }); + }); + + test('应使用指定的编码解码文本', () { + var string = 'blåbærgrød'; + var encoded = latin1.encoder.convert(string); + var data = [encoded.sublist(0, 4), encoded.sublist(4)]; + var stream = Stream>.fromIterable(data); + byteStreamToString(stream, encoding: latin1).then((decoded) { + expect(decoded, string); + }); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/cache/map_cache_test.dart b/ohos/test_quiver/lib/src/cache/map_cache_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f9014c897b2bf60469072f05e9928fc9ce317680 --- /dev/null +++ b/ohos/test_quiver/lib/src/cache/map_cache_test.dart @@ -0,0 +1,114 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.cache.map_cache_test; + +import 'dart:async'; + +import 'package:quiver/src/cache/map_cache.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class MapCacheTestPage extends TestPage { + MapCacheTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('MapCache', () { + cache = MapCache(); + + test('对于不存在的键,应返回null', () { + return cache.get('foo1').then((value) { + expect(value, null); + }); + }); + + test('应返回以前设置的键/值对', () { + return cache + .set('foo', 'bar') + .then((_) => cache.get('foo')) + .then((value) { + expect(value, 'bar'); + }); + }); + + test('应该使密钥无效', () { + return cache + .set('foo', 'bar') + .then((_) => cache.invalidate('foo')) + .then((_) => cache.get('foo')) + .then((value) { + expect(value, null); + }); + }); + + test('如果没有值且没有ifAbsent处理程序,则应返回null', () { + return cache.get('foo').then((value) { + expect(value, null); + }); + }); + + test('应该加载给定同步加载程序的值', () { + return cache.get('foo', ifAbsent: (k) => k + k).then((value) { + expect(value, 'foofoo'); + }); + }); + + test('应该加载给定异步加载程序的值', () { + return cache + .get('foo', ifAbsent: (k) => Future.value(k + k)) + .then((value) { + expect(value, 'foofoo'); + }); + }); + + test('不应对同一密钥进行多次请求', () async { + final completer = Completer(); + int count = 0; + + Future loader(String key) { + count += 1; + return completer.future; + } + + final futures = Future.wait([ + cache.get('test', ifAbsent: loader), + cache.get('test', ifAbsent: loader), + ]); + + completer.complete('bar'); + expect(count, 1); + expect(await futures, ['bar', 'bar']); + }); + + test('缓存失败的请求', () async { + int count = 0; + + Future failLoader(String key) async { + count += 1; + throw StateError('Request failed'); + } + + await cache.get('test', ifAbsent: failLoader); + await cache.get('test', ifAbsent: failLoader); + + expect(count, 2); + expect(await cache.get('test'), null); + + // Make sure it doesn't block a later successful load. + await cache.get('test', ifAbsent: (key) => 'bar'); + }); + }); + } + + late MapCache cache; +} diff --git a/ohos/test_quiver/lib/src/check_test.dart b/ohos/test_quiver/lib/src/check_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b5e7fa96de0e40f01239c1b239a923ec47c32c76 --- /dev/null +++ b/ohos/test_quiver/lib/src/check_test.dart @@ -0,0 +1,155 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +library quiver.check_test; + +import 'package:quiver/check.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CheckTestPage extends TestPage { + CheckTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('checkArgument', () { + group('success', () { + test('简单的检查', () => checkArgument(true)); + test('空消息', () => checkArgument(true, message: null)); + test('字符串消息', () => checkArgument(true, message: 'foo')); + test('功能消息', () => checkArgument(true, message: () => fail("Shouldn't be called"))); + }); + + group('failure', () { + void checkArgumentShouldFail(Function f, [String? expectedMessage]) { + try { + f(); + fail('Should have thrown an ArgumentError'); + } on ArgumentError catch (e) { + expect(e.message, expectedMessage); + } + } + + test('无消息', () => checkArgumentShouldFail(() => checkArgument(false))); + + test('故障和简单字符串消息', () => checkArgumentShouldFail(() => checkArgument(false, message: 'message'), 'message')); + + test('失败和空消息', () => checkArgumentShouldFail(() => checkArgument(false, message: null))); + test('失败并将对象作为消息', () => checkArgumentShouldFail(() => checkArgument(false, message: 5), '5')); + test('失败,消息关闭返回对象', () => checkArgumentShouldFail(() => checkArgument(false, message: () => 5), '5')); + + test('故障和消息功能', () { + int five = 5; + checkArgumentShouldFail(() => checkArgument(false, message: () => 'I ate $five pies'), 'I ate 5 pies'); + }); + }); + }); + + group('checkState', () { + group('success', () { + test('简单的', () => checkState(true)); + test('空消息', () => checkState(true, message: null)); + test('字符串消息', () => checkState(true, message: 'foo')); + test('功能消息', () => checkState(true, message: () => fail("Shouldn't be called"))); + }); + + group('failure', () { + void checkStateShouldFail(Function f, [String? expectedMessage]) { + expectedMessage ??= 'failed precondition'; + try { + f(); + fail('Should have thrown a StateError'); + } on StateError catch (e) { + expect(e.message, expectedMessage); + } + } + + test('无消息', () => checkStateShouldFail(() => checkState(false))); + + test('故障和简单字符串消息', () => checkStateShouldFail(() => checkState(false, message: 'message'), 'message')); + + test('失败和空消息', () => checkStateShouldFail(() => checkState(false, message: null))); + test('消息闭包返回null', () => checkStateShouldFail(() => checkState(false, message: () => null))); + + test('故障和消息功能', () { + int five = 5; + checkStateShouldFail(() => checkState(false, message: () => 'I ate $five pies'), 'I ate 5 pies'); + }); + }); + }); + + group('checkNotNull', () { + group('success', () { + test('简单的', () => expect(checkNotNull(''), '')); + test('字符串消息', () => expect(checkNotNull(5, message: 'foo'), 5)); + test('函数消息', () => expect(checkNotNull(true, message: () => fail("Shouldn't be called")), true)); + }); + + group('failure', () { + void checkNotNullShouldFail(Function f, [String? expectedMessage]) { + expectedMessage ??= 'null pointer'; + try { + f(); + fail('Should have thrown an ArgumentError'); + } on ArgumentError catch (e) { + expect(e.message, expectedMessage); + } + } + + test('无消息', () => checkNotNullShouldFail(() => checkNotNull(null))); + + test('简单故障消息', () => checkNotNullShouldFail(() => checkNotNull(null, message: 'message'), 'message')); + + test('空消息', () => checkNotNullShouldFail(() => checkNotNull(null, message: null))); + + test('消息闭包返回null', () => checkNotNullShouldFail(() => checkNotNull(null, message: () => null))); + + test('故障和消息功能', () { + int five = 5; + checkNotNullShouldFail(() => checkNotNull(null, message: () => 'I ate $five pies'), 'I ate 5 pies'); + }); + }); + }); + + group('checkListIndex', () { + test('success', () { + checkListIndex(0, 1); + checkListIndex(0, 1, message: () => fail("shouldn't be called")); + checkListIndex(0, 2); + checkListIndex(0, 2, message: () => fail("shouldn't be called")); + checkListIndex(1, 2); + checkListIndex(1, 2, message: () => fail("shouldn't be called")); + }); + + group('failure', () { + void checkListIndexShouldFail(int index, int size, [message, String? expectedMessage]) { + try { + checkListIndex(index, size, message: message); + fail('Should have thrown a RangeError'); + } on RangeError catch (e) { + expect(e.message, expectedMessage ?? 'index $index not valid for list of size $size'); + } + } + + test('底片尺寸', () => checkListIndexShouldFail(0, -1)); + test('下标', () => checkListIndexShouldFail(-1, 1)); + test('下标太大', () => checkListIndexShouldFail(1, 1)); + test('大小为零', () => checkListIndexShouldFail(0, 0)); + + test('带有故障消息', () => checkListIndexShouldFail(1, 1, 'foo', 'foo')); + test('具有故障消息功能', () { + int five = 5; + checkListIndexShouldFail(1, 1, () => 'I ate $five pies', 'I ate 5 pies'); + }); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/collection/bimap_test.dart b/ohos/test_quiver/lib/src/collection/bimap_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e429020556bd5f173ec20c36dba067743507d86e --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/bimap_test.dart @@ -0,0 +1,426 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.bimap_test; + +import 'package:quiver/src/collection/bimap.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; +import 'package:matcher/src/expect/throws_matcher.dart'; + +class BimapTestPage extends TestPage { + BimapTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('BiMap', () { + test('should construct a HashBiMap', () { + expect(BiMap() is HashBiMap, true); + }); + }); + + group('HashBiMap', () { + late BiMap map; + const String k1 = 'k1', k2 = 'k2', k3 = 'k3'; + const int v1 = 1, v2 = 2, v3 = 3; + + map = HashBiMap(); + + test('应初始化为空', () { + expect(map.isEmpty, true); + expect(map.isNotEmpty, false); + expect(map.inverse.isEmpty, true); + expect(map.inverse.isNotEmpty, false); + }); + + test('应支持空键', () { + final map = BiMap(); + map[null] = 5; + expect(map.isEmpty, false); + expect(map.containsKey(null), true); + expect(map.containsValue(5), true); + expect(map.keys, map.keys.contains(null)); + + expect(map.inverse.containsKey(5), true); + expect(map.inverse.containsValue(null), true); + expect(map.inverse.keys, map.inverse.keys.contains(5)); + }); + + test('应支持null值', () { + final map = BiMap(); + map[k1] = null; + expect(map.isEmpty, false); + expect(map.containsKey(k1), true); + expect(map.containsValue(null), true); + expect(map[k1], null); + }); + + test('添加映射后不应为空', () { + map[k1] = v1; + expect(map.isEmpty, false); + expect(map.isNotEmpty, true); + expect(map.inverse.isEmpty, false); + expect(map.inverse.isNotEmpty, true); + }); + + test('反向添加映射后不应为空', () { + map.inverse[v1] = k1; + expect(map.isEmpty, false); + expect(map.isNotEmpty, true); + expect(map.inverse.isEmpty, false); + expect(map.inverse.isNotEmpty, true); + }); + + test('应包含添加的映射', () { + map[k1] = v1; + map[k2] = v2; + expect(map[k1], v1); + expect(map[k2], v2); + expect(map.inverse[v1], k1); + expect(map.inverse[v2], k2); + }); + + test('应允许覆盖现有keys', () { + map = HashBiMap(); + map[k1] = v1; + map[k1] = v2; + expect(map[k1], v2); + expect(map.inverse.containsKey(v1), false); + expect(map.inverse[v2], k1); + }); + + test('应允许通过其反向键覆盖现有键', () { + map = HashBiMap(); + map.inverse[v1] = k1; + map.inverse[v1] = k2; + expect(map[k2], v1); + expect(map.inverse.containsKey(v2), false); + expect(map.inverse[v1], k2); + }); + + test('应允许覆盖现有键值对', () { + map = HashBiMap(); + map[k1] = v1; + map[k1] = v1; + expect(map[k1], v1); + expect(map.inverse.containsKey(v1), true); + expect(map.inverse[v1], k1); + }); + + test('应允许通过其反向覆盖现有键值对', + () { + map.inverse[v1] = k1; + map.inverse[v1] = k1; + expect(map[k1], v1); + expect(map.inverse.containsKey(v1), true); + expect(map.inverse[v1], k1); + }); + + test('应该使用映射值覆盖未映射的键', () { + map = HashBiMap(); + map[k1] = v1; + expect(map.containsKey(k2), false); + expect(map.inverse.containsValue(k2), false); + }); + + test('应该使用映射的null值覆盖未映射的键', + () { + final map1 = BiMap(); + map1[k1] = null; + expect(map1.containsKey(k2), false); + expect(map1.inverse.containsValue(k2), false); + }); + + test( + '应该通过反向使用映射值覆盖未映射的键', + () { + map = HashBiMap(); + map[k1] = v1; + expect(map.containsValue(v2), false); + }); + + test( + '应该通过反向使用映射的null值覆盖未映射的键', + () { + final map1 = BiMap(); + map1[null] = v1; + }); + + test('应允许强制添加具有映射值的未映射关键帧', () { + map[k1] = v1; + map.replace(k2, v1); + expect(map[k2], v1); + expect(map.containsKey(k1), false); + expect(map.inverse[v1], k2); + expect(map.inverse.containsValue(k1), false); + }); + + test( + '应允许通过反向强制添加具有映射值的未映射关键帧', + () { + map.inverse[v1] = k1; + map.inverse.replace(v2, k1); + expect(map[k1], v2); + expect(map.containsValue(v1), false); + expect(map.inverse[v2], k1); + expect(map.inverse.containsKey(v1), false); + }); + + test('不应包含已删除的 mappings', () { + map[k1] = v1; + map.remove(k1); + expect(map.containsKey(k1), false); + expect(map.inverse.containsKey(v1), false); + + map[k1] = v1; + map[k2] = v2; + map.removeWhere((k, v) => v.isOdd); + expect(map.containsKey(k1), false); + expect(map.containsKey(k2), true); + expect(map.inverse.containsKey(v1), false); + expect(map.inverse.containsKey(v2), true); + }); + + test('不应包含从其反向中删除的映射', () { + map[k1] = v1; + map.inverse.remove(v1); + expect(map.containsKey(k1), false); + expect(map.inverse.containsKey(v1), false); + + map[k1] = v1; + map[k2] = v2; + map.inverse.removeWhere((v, k) => v.isOdd); + expect(map.containsKey(k1), false); + expect(map.containsKey(k2), true); + expect(map.inverse.containsKey(v1), false); + expect(map.inverse.containsKey(v2), true); + }); + + test('应该更新双方', () { + map[k1] = v1; + map.update(k1, (v) => v + 1); + expect(map[k1], v1 + 1); + expect(map.inverse[v1 + 1], k1); + + map[k1] = v1; + map.inverse.update(v1, (k) => '_$k'); + expect(map['_$k1'], v1); + expect(map.inverse[v1],'_$k1'); + }); + + test('应更新缺少的键值', () { + map = HashBiMap(); + map[k1] = v1; + map.update(k2, (v) => v + 1, ifAbsent: () => 0); + map[k1] = v1; + map.inverse.update(v2, (k) => '_$k', ifAbsent: () => '_X'); + expect(map['_X'], v2); + expect(map.inverse[v2], '_X'); + }); + + test('应更新所有值', () { + map = HashBiMap(); + map[k1] = v1; + map[k2] = v2; + map.updateAll((k, v) => v + k.length); + + expect(map.inverse[3], k1); + expect(map.inverse[4], k2); + }); + + test('清除后应为空', () { + map[k1] = v1; + map[k2] = v2; + map.clear(); + }); + + test('inverte.clear之后应为空', () { + map[k1] = v1; + map[k2] = v2; + map.inverse.clear(); + expect(map.isEmpty, true); + }); + + test('应包含映射的键', () { + map[k1] = v1; + map[k2] = v2; + expect(map.containsKey(k1), true); + expect(map.containsKey(k2), true); + expect(map.inverse.containsKey(v1), true); + expect(map.inverse.keys, [v1, v2]); + }); + + test('应包含通过其反向映射的关键帧', () { + map.inverse[v1] = k1; + map.inverse[v2] = k2; + expect(map.containsKey(k1), true); + expect(map.containsKey(k2), true); + expect(map.keys, [k1, k2]); + expect(map.inverse.containsKey(v1), true); + expect(map.inverse.containsKey(v2), true); + expect(map.inverse.keys, [v1, v2]); + }); + + test('应包含 mapped values', () { + map[k1] = v1; + map[k2] = v2; + expect(map.containsValue(v1), true); + expect(map.containsValue(v2), true); + expect(map.values, [v1, v2]); + expect(map.inverse.containsValue(k1), true); + expect(map.inverse.containsValue(k2), true); + expect(map.inverse.values, [k1, k2]); + }); + + test('应包含通过其反向映射的值', () { + map.inverse[v1] = k1; + map.inverse[v2] = k2; + expect(map.containsValue(v1), true); + expect(map.containsValue(v2), true); + expect(map.values, [v1, v2]); + expect(map.inverse.containsValue(k1), true); + expect(map.inverse.containsValue(k2), true); + expect(map.inverse.values, [k1, k2]); + }); + + test('应添加 entries', () { + map.addEntries(const [MapEntry(k1, v1)]); + expect(map[k1], v1); + expect(map.inverse[v1], k1); + + map.inverse.addEntries(const [MapEntry(v2, k2)]); + expect(map[k2], v2); + expect(map.inverse[v2], k2); + }); + + test('获取 entries', () { + map[k1] = v1; + map.inverse[v2] = k2; + + var mapEntries = map.entries; + expect(mapEntries, 2); + // MapEntry objects are not equal to each other; cannot use `contains`. :( + expect(mapEntries.singleWhere((e) => e.key == k1).value, v1); + expect(mapEntries.singleWhere((e) => e.key == k2).value, v2); + + var inverseEntries = map.inverse.entries; + expect(inverseEntries, 2); + expect(inverseEntries.singleWhere((e) => e.key == v1).value, k1); + expect(inverseEntries.singleWhere((e) => e.key == v2).value, k2); + }); + + test(' map 映射', () { + map[k1] = v1; + map[k2] = v2; + + var mapped = map.map((k, v) => MapEntry(k.toUpperCase(), '$k / $v')); + expect(mapped, 'K1'); + expect(mapped, 'K2'); + expect(mapped['K1'], 'k1 / 1'); + expect(mapped['K2'], 'k2 / 2'); + + var mapped2 = map.inverse.map((v, k) => MapEntry('$v$v', k.length)); + expect(mapped2, '11'); + expect(mapped2, '22'); + expect(mapped2['11'], 2); + expect(mapped2['22'], 2); + }); + + test('如果不存在,则应通过putIfAbsent添加映射', () { + map.putIfAbsent(k1, () => v1); + expect(map[k1], v1); + expect(map.inverse[v1], k1); + }); + + test('应通过inverte.putIfAbsent添加映射(如果不存在)', () { + map.inverse.putIfAbsent(v1, () => k1); + expect(map[k1], v1); + expect(map.inverse[v1], k1); + }); + + test('不应通过putIfAbsent添加映射(如果存在)', () { + map[k1] = v1; + map.putIfAbsent(k1, () => v2); + expect(map[k1], v1); + expect(map.inverse[v1], k1); + expect(map.inverse.containsKey(v2), false); + }); + + test('不应通过inverte.putIfAbsent添加映射(如果存在)', () { + map[k1] = v1; + map.inverse.putIfAbsent(v1, () => k2); + expect(map[k1], v1); + expect(map.containsKey(k2), false); + expect(map.inverse[v1], k1); + }); + + test('应包含从另一个映射添加的映射', () { + map.addAll({k1: v1, k2: v2, k3: v3}); + expect(map[k1], v1); + expect(map[k2], v2); + expect(map[k3], v3); + expect(map.inverse[v1], k1); + expect(map.inverse[v2], k2); + expect(map.inverse[v3], k3); + }); + + test('应包含从另一个映射通过其反向添加的映射', () { + map.inverse.addAll({v1: k1, v2: k2, v3: k3}); + expect(map[k1], v1); + expect(map[k2], v2); + expect(map[k3], v3); + expect(map.inverse[v1], k1); + expect(map.inverse[v2], k2); + expect(map.inverse[v3], k3); + }); + + test('应返回键值对的数量作为其长度', () { + map = HashBiMap(); + expect(map.length, 0); + map[k1] = v1; + expect(map.length, 1); + map[k1] = v2; + expect(map.length, 1); + map.replace(k2, v2); + expect(map.length, 1); + map[k1] = v1; + expect(map.length, 2); + }); + + test('应通过forEach迭代所有对', () { + map[k1] = v1; + map[k2] = v2; + var keys = []; + var values = []; + map.forEach((k, v) { + keys.add(k); + values.add(v); + }); + expect(keys, [k1, k2]); + expect(values, [v1, v2]); + }); + + test('应通过其逆函数的forEach迭代所有对', () { + map[k1] = v1; + map[k2] = v2; + var keys = []; + var values = []; + map.inverse.forEach((k, v) { + keys.add(k); + values.add(v); + }); + expect(keys, [v1, v2]); + expect(values, [k1, k2]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/collection/delegates/iterable_test.dart b/ohos/test_quiver/lib/src/collection/delegates/iterable_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9e7b6d853ff385e3914c15ebdda197d2ea0ac1e3 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/delegates/iterable_test.dart @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.delegates.iterable_test; + +import 'package:quiver/src/collection/delegates/iterable.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class MyIterable extends DelegatingIterable { + MyIterable(this._delegate); + + final Iterable _delegate; + + @override + Iterable get delegate => _delegate; +} + +class IterableTestPage extends TestPage { + IterableTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('DelegatingIterable', () { + late DelegatingIterable delegatingIterable; + + delegatingIterable = MyIterable(['a', 'b', 'cc']); + + test('any', () { + expect(delegatingIterable.any((e) => e == 'b'), true); + expect(delegatingIterable.any((e) => e == 'd'), false); + }); + + test('contains', () { + expect(delegatingIterable.contains('b'), true); + expect(delegatingIterable.contains('d'), false); + }); + + test('elementAt', () { + expect(delegatingIterable.elementAt(1), 'b'); + }); + + test('every', () { + expect(delegatingIterable.every((e) => true), true); + expect(delegatingIterable.every((e) => e == 'b'), false); + }); + + test('expand', () { + expect(delegatingIterable.expand((e) => e.codeUnits), [97, 98, 99, 99]); + }); + + test('first', () { + expect(delegatingIterable.first, 'a'); + }); + + test('firstWhere', () { + expect(delegatingIterable.firstWhere((e) => e == 'b'), 'b'); + expect( + delegatingIterable.firstWhere((e) => e == 'd', orElse: () => 'e'), + 'e'); + }); + + // test('fold', () { + // expect(delegatingIterable.fold('z', (String p, String e) => p + e), + // equals('zabcc')); + // }); + + test('forEach', () { + final s = StringBuffer(); + delegatingIterable.forEach(s.write); + expect(s.toString(), 'abcc'); + }); + + test('isEmpty', () { + expect(delegatingIterable.isEmpty, false); + expect(MyIterable([]).isEmpty, true); + }); + + test('isNotEmpty', () { + expect(delegatingIterable.isNotEmpty, true); + expect(MyIterable([]).isNotEmpty, false); + }); + + test('followedBy', () { + expect(delegatingIterable.followedBy(['d', 'e']), + ['a', 'b', 'cc', 'd', 'e']); + expect(delegatingIterable.followedBy(delegatingIterable), + ['a', 'b', 'cc', 'a', 'b', 'cc']); + }); + + test('forEach', () { + final it = delegatingIterable.iterator; + expect(it.moveNext(), true); + expect(it.current, 'a'); + expect(it.moveNext(), true); + expect(it.current, 'b'); + expect(it.moveNext(), true); + expect(it.current, 'cc'); + expect(it.moveNext(), false); + }); + + test('join', () { + expect(delegatingIterable.join(), 'abcc'); + expect(delegatingIterable.join(','), 'a,b,cc'); + }); + + test('last', () { + expect(delegatingIterable.last, 'cc'); + }); + + test('lastWhere', () { + expect(delegatingIterable.lastWhere((e) => e == 'b'), 'b'); + expect(delegatingIterable.lastWhere((e) => e == 'd', orElse: () => 'e'), + 'e'); + }); + + test('length', () { + expect(delegatingIterable.length, 3); + }); + + test('map', () { + expect( + delegatingIterable.map((e) => e.toUpperCase()), ['A', 'B', 'CC']); + }); + + test('reduce', () { + expect(delegatingIterable.reduce((value, element) => value + element), + 'abcc'); + }); + + test('single, 此处应为x', () { + delegatingIterable.single; + expect(MyIterable(['a']).single, 'a'); + }); + + test('singleWhere', () { + expect(delegatingIterable.singleWhere((e) => e == 'b'), 'b'); + expect( + delegatingIterable.singleWhere((e) => e == 'd', orElse: () => 'X'), + 'X'); + }); + + test('skip', () { + expect(delegatingIterable.skip(1), ['b', 'cc']); + }); + + test('skipWhile', () { + expect(delegatingIterable.skipWhile((e) => e == 'a'), ['b', 'cc']); + }); + + test('take', () { + expect(delegatingIterable.take(1), ['a']); + }); + + test('skipWhile', () { + expect(delegatingIterable.takeWhile((e) => e == 'a'), ['a']); + }); + + test('toList', () { + expect(delegatingIterable.toList(), ['a', 'b', 'cc']); + }); + + test('toSet', () { + expect(delegatingIterable.toSet(), {'a', 'b', 'cc'}); + }); + + test('where', () { + expect(delegatingIterable.where((e) => e.length == 1), ['a', 'b']); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/collection/delegates/list_test.dart b/ohos/test_quiver/lib/src/collection/delegates/list_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c85314fec8b929ac5ecfb1b825e25c6dc7663062 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/delegates/list_test.dart @@ -0,0 +1,181 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.delegates.list_test; + +import 'package:quiver/src/collection/delegates/list.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class MyList extends DelegatingList { + MyList(this._delegate); + + final List _delegate; + + @override + List get delegate => _delegate; +} + +class ListTestPage extends TestPage { + ListTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('DelegatingList', () { + DelegatingList delegatingList = MyList(['a', 'b', 'cc']); + test('依据下标获取值', () { + expect(delegatingList[1], 'b'); + expect(delegatingList[2], 'cc'); + }); + + test('[]=', () { + delegatingList[0] = 'd'; + expect(delegatingList, ['d', 'b', 'cc']); + }); + + test('+', () { + var sum = delegatingList + ['d', 'e']; + expect(sum, ['a', 'b', 'cc', 'd', 'e']); + }); + + test('add', () { + delegatingList.add('d'); + expect(delegatingList, ['a', 'b', 'cc', 'd']); + }); + + test('addAll', () { + delegatingList.addAll(['d', 'e']); + expect(delegatingList, ['a', 'b', 'cc', 'd', 'e']); + }); + + test('asMap', () { + expect(delegatingList.asMap(), {0: 'a', 1: 'b', 2: 'cc'}); + }); + + test('clear', () { + delegatingList.clear(); + expect(delegatingList, []); + }); + + test('fillRange', () { + DelegatingList nullableDelegatingList = + MyList(['a', 'b', 'cc']); + nullableDelegatingList.fillRange(0, 2); + expect(nullableDelegatingList, [null, null, 'cc']); + + expect(delegatingList, ['d', 'd', 'cc']); + }); + + test('getRange', () { + delegatingList = MyList(['a', 'b', 'cc']); + expect(delegatingList.getRange(1, 2), ['b']); + }); + + test('indexOf', () { + expect(delegatingList.indexOf('b'), 1); + expect(delegatingList.indexOf('a', 1), -1); + expect(delegatingList.indexOf('cc', 1), 2); + }); + + test('indexWhere', () { + delegatingList.add('bb'); + expect(delegatingList.indexWhere((e) => e.length > 1), 2); + }); + + test('insert', () { + delegatingList.insert(1, 'd'); + expect(delegatingList, ['a', 'd', 'b', 'cc']); + }); + + test('insertAll', () { + delegatingList.insertAll(1, ['d', 'e']); + expect(delegatingList, ['a', 'd', 'e', 'b', 'cc']); + }); + + test('lastIndexOf', () { + expect(delegatingList.lastIndexOf('b'), 1); + expect(delegatingList.lastIndexOf('a', 1), 0); + expect(delegatingList.lastIndexOf('cc', 1), -1); + }); + + test('lastIndexWhere', () { + delegatingList.add('bb'); + expect(delegatingList.lastIndexWhere((e) => e.length > 1), 3); + }); + + test('set length', () { + delegatingList.length = 2; + expect(delegatingList, ['a', 'b']); + }); + + test('remove', () { + delegatingList.remove('b'); + expect(delegatingList, ['a', 'cc']); + }); + + test('removeAt', () { + delegatingList.removeAt(1); + expect(delegatingList, ['a', 'cc']); + }); + + test('removeLast', () { + delegatingList.removeLast(); + expect(delegatingList, ['a', 'b']); + }); + + test('removeRange', () { + delegatingList = MyList(['a', 'b', 'cc']); + delegatingList.removeRange(1, 2); + }); + + test('removeWhere', () { + delegatingList.removeWhere((e) => e.length == 1); + expect(delegatingList, ['cc']); + }); + + test('replaceRange', () { + delegatingList = MyList(['a', 'b', 'cc']); + delegatingList.replaceRange(1, 2, ['d', 'e']); + expect(delegatingList, ['a', 'd', 'e', 'cc']); + }); + + test('retainWhere', () { + delegatingList.retainWhere((e) => e.length == 1); + expect(delegatingList, ['a', 'b']); + }); + + test('reversed', () { + expect(delegatingList.reversed, ['cc', 'b', 'a']); + }); + + test('setAll', () { + delegatingList.setAll(1, ['d', 'e']); + expect(delegatingList, ['a', 'd', 'e']); + }); + + test('setRange', () { + delegatingList.setRange(1, 3, ['d', 'e']); + expect(delegatingList, ['a', 'd', 'e']); + }); + + test('sort', () { + delegatingList.sort((a, b) => b.codeUnitAt(0) - a.codeUnitAt(0)); + expect(delegatingList, ['cc', 'b', 'a']); + }); + + test('sublist', () { + expect(delegatingList.sublist(1), ['b', 'cc']); + expect(delegatingList.sublist(1, 2), ['b']); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/collection/delegates/map_test.dart b/ohos/test_quiver/lib/src/collection/delegates/map_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..42f95e459c923299ea8cb1250a01df59d1635701 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/delegates/map_test.dart @@ -0,0 +1,109 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.delegates.map_test; + +import 'package:quiver/src/collection/delegates/map.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class MyMap extends DelegatingMap { + MyMap(this._delegate); + + final Map _delegate; + + @override + Map get delegate => _delegate; +} + +class MapTestPage extends TestPage { + MapTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('DelegatingMap', () { + DelegatingMap delegatingMap = MyMap({'a': 1, 'bb': 2}); + + test('依据key获取值', () { + DelegatingMap delegatingMap = MyMap({'a': 1, 'bb': 2}); + expect(delegatingMap['a'], 1); + expect(delegatingMap['bb'], 2); + expect(delegatingMap['c'], null); + }); + + test('[]=', () { + delegatingMap['a'] = 3; + delegatingMap['c'] = 4; + expect(delegatingMap, {'a': 3, 'bb': 2, 'c': 4}); + }); + + test('addAll', () { + delegatingMap.addAll({'a': 3, 'c': 4}); + expect(delegatingMap, {'a': 3, 'bb': 2, 'c': 4}); + }); + + test('clear', () { + delegatingMap.clear(); + expect(delegatingMap, {}); + }); + + test('containsKey', () { + expect(delegatingMap.containsKey('a'), true); + expect(delegatingMap.containsKey('b'), false); + }); + + test('containsValue', () { + expect(delegatingMap.containsValue(1), true); + expect(delegatingMap.containsValue('b'), false); + }); + + test('forEach', () { + final s = StringBuffer(); + delegatingMap.forEach((k, v) => s.write('$k$v')); + expect(s.toString(), 'a1bb2'); + }); + + test('isEmpty', () { + expect(delegatingMap.isEmpty, false); + expect(MyMap({}).isEmpty, true); + }); + + test('isNotEmpty', () { + expect(delegatingMap.isNotEmpty, true); + expect(MyMap({}).isNotEmpty, false); + }); + + test('keys', () { + expect(delegatingMap.keys, ['a', 'bb']); + }); + + test('length', () { + expect(delegatingMap.length, 2); + expect(MyMap({}).length, 0); + }); + + test('putIfAbsent', () { + expect(delegatingMap.putIfAbsent('c', () => 4), 4); + expect(delegatingMap.putIfAbsent('c', () => throw ''), 4); + }); + + test('remove', () { + expect(delegatingMap.remove('a'), 1); + expect(delegatingMap, {'bb': 2}); + }); + + test('values', () { + expect(delegatingMap.values, [1, 2]); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/collection/delegates/queue_test.dart b/ohos/test_quiver/lib/src/collection/delegates/queue_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f798b654c09247d929f06b67320107368253ee59 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/delegates/queue_test.dart @@ -0,0 +1,82 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.delegates.queue_test; + +import 'dart:collection' show Queue; + +import 'package:quiver/src/collection/delegates/queue.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class MyQueue extends DelegatingQueue { + MyQueue(this._delegate); + + final Queue _delegate; + + @override + Queue get delegate => _delegate; +} + +class QueueTestPage extends TestPage { + QueueTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('DelegatingQueue', () { + late DelegatingQueue delegatingQueue; + + delegatingQueue = MyQueue(Queue.from(['a', 'b', 'cc'])); + + test('add', () { + delegatingQueue.add('d'); + expect(delegatingQueue, ['a', 'b', 'cc', 'd']); + }); + + test('addAll', () { + delegatingQueue.addAll(['d', 'e']); + expect(delegatingQueue, ['a', 'b', 'cc', 'd', 'e']); + }); + + test('addFirst', () { + delegatingQueue.addFirst('d'); + expect(delegatingQueue, ['d', 'a', 'b', 'cc']); + }); + + test('addLast', () { + delegatingQueue.addLast('d'); + expect(delegatingQueue, ['a', 'b', 'cc', 'd']); + }); + + test('clear', () { + delegatingQueue.clear(); + expect(delegatingQueue, []); + }); + + test('remove', () { + expect(delegatingQueue.remove('b'), true); + expect(delegatingQueue, ['a', 'cc']); + }); + + test('removeFirst', () { + delegatingQueue = MyQueue(Queue.from(['a', 'b', 'cc'])); + expect(delegatingQueue.removeFirst(), 'a'); + expect(delegatingQueue, ['b', 'cc']); + }); + + test('removeLast', () { + expect(delegatingQueue.removeLast(), 'cc'); + expect(delegatingQueue, ['a', 'b']); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/collection/delegates/set_test.dart b/ohos/test_quiver/lib/src/collection/delegates/set_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..243c74479736f4f57d3fb82bdc68aa3fbb70c35f --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/delegates/set_test.dart @@ -0,0 +1,100 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.delegates.set_test; + +import 'package:quiver/src/collection/delegates/set.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class MySet extends DelegatingSet { + MySet(this._delegate); + + final Set _delegate; + + @override + Set get delegate => _delegate; +} + +class SetTestPage extends TestPage { + SetTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('DelegatingSet', () { + late DelegatingSet delegatingSet; + + delegatingSet = MySet({'a', 'b', 'cc'}); + + test('add', () { + delegatingSet.add('d'); + expect(delegatingSet, ['a', 'b', 'cc', 'd']); + delegatingSet.add('d'); + expect(delegatingSet, ['a', 'b', 'cc', 'd']); + }); + + test('addAll', () { + delegatingSet.addAll(['d', 'e']); + expect(delegatingSet, ['a', 'b', 'cc', 'd', 'e']); + }); + + test('clear', () { + delegatingSet.clear(); + expect(delegatingSet, []); + }); + + test('containsAll', () { + expect(delegatingSet.containsAll(['a', 'cc']), true); + expect(delegatingSet.containsAll(['a', 'c']), false); + }); + + test('difference', () { + expect(delegatingSet.difference({'a', 'cc'}), ['b']); + expect(delegatingSet.difference({'cc'}), ['a', 'b']); + }); + + test('intersection', () { + expect(delegatingSet.intersection({'a', 'dd'}), ['a']); + expect(delegatingSet.intersection({'e'}), []); + }); + + test('remove', () { + expect(delegatingSet.remove('b'), true); + expect(delegatingSet, ['a', 'cc']); + }); + + test('removeAll', () { + delegatingSet.removeAll(['a', 'cc']); + expect(delegatingSet, ['b']); + }); + + test('removeWhere', () { + delegatingSet.removeWhere((e) => e.length == 1); + expect(delegatingSet, ['cc']); + }); + + test('retainAll', () { + delegatingSet.retainAll(['a', 'cc', 'd']); + expect(delegatingSet, ['a', 'cc']); + }); + + test('retainWhere', () { + delegatingSet.retainWhere((e) => e.length == 1); + expect(delegatingSet, ['a', 'b']); + }); + + test('union', () { + expect(delegatingSet.union({'a', 'cc', 'd'}), ['a', 'b', 'cc', 'd']); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/collection/lru_map_test.dart b/ohos/test_quiver/lib/src/collection/lru_map_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a15537df45da148c04ebf4bbda5515bcf17d73f3 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/lru_map_test.dart @@ -0,0 +1,347 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +library quiver.collection.lru_map_test; + +import 'package:quiver/src/collection/lru_map.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class LruMapTestPage extends TestPage { + LruMapTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('LruMap', () { + /// A map that will be initialized by individual tests. + late LruMap lruMap; + + test('length属性反映映射中的键数', () { + lruMap = LruMap(); + expect(lruMap, lruMap.length==0); + + lruMap.addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + expect(lruMap, lruMap.length==3); + }); + + test('访问密钥', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + + // Trigger promotion of B. + final _ = lruMap['B']; + + // In a LRU cache, the first key is the one that will be removed if the + // capacity is reached, so adding keys to the end is considered to be a + // 'promotion'. + expect(lruMap.keys.toList(), ['B', 'C', 'A']); + }); + + test('在开头添加新密钥', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + lruMap['D'] = 'Delta'; + expect(lruMap.keys.toList(), ['D', 'C', 'B', 'A']); + }); + + test('在现有密钥上设置值有效,并提升密钥', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + lruMap['B'] = 'Bravo'; + expect(lruMap.keys.toList(), ['B', 'C', 'A']); + expect(lruMap['B'], 'Bravo'); + }); + + test('更新现有密钥的值有效,并提升密钥', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + lruMap.update('B', (v) => '$v$v'); + expect(lruMap.keys.toList(), ['B', 'C', 'A']); + expect(lruMap['B'], 'BetaBeta'); + }); + + test('更新缺少密钥的值有效,并提升密钥', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + lruMap.update('D', (v) => '$v$v', ifAbsent: () => 'Delta'); + expect(lruMap.keys.toList(), ['D', 'C', 'B', 'A']); + expect(lruMap['D'], 'Delta'); + }); + + test('更新所有值有效,不会更改已使用的顺序', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + lruMap.updateAll((k, v) => '$v$v'); + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + expect(lruMap['A'], 'AlphaAlpha'); + expect(lruMap['B'], 'BetaBeta'); + expect(lruMap['C'], 'CharlieCharlie'); + }); + + test('当容量达到时,最近最少使用的密钥将被收回', () { + lruMap = LruMap(maximumSize: 3) + ..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + lruMap['D'] = 'Delta'; + expect(lruMap.keys.toList(), ['D', 'C', 'B']); + }); + + test('设置最大大小将逐出关键帧,直到达到该大小为止', () { + lruMap = LruMap(maximumSize: 5) + ..addAll({ + 'A': 'Alpha', + 'B': 'Beta', + 'C': 'Charlie', + 'D': 'Delta', + 'E': 'Epsilon' + }); + + lruMap.maximumSize = 3; + expect(lruMap.keys.toList(), ['E', 'D', 'C']); + }); + + test('访问“keys”集合不会影响位置', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + + void nop(String key) {} + lruMap.keys.forEach(nop); + lruMap.keys.forEach(nop); + + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + }); + + test('访问“values”集合不会影响位置', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.values.toList(), ['Charlie', 'Beta', 'Alpha']); + + void nop(String key) {} + lruMap.values.forEach(nop); + lruMap.values.forEach(nop); + + expect(lruMap.values.toList(), ['Charlie', 'Beta', 'Alpha']); + }); + + test('清除将删除所有键和值', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.isNotEmpty, true); + expect(lruMap.keys.isNotEmpty, true); + expect(lruMap.values.isNotEmpty, true); + + lruMap.clear(); + + expect(lruMap.isEmpty, true); + expect(lruMap.keys.isEmpty, true); + expect(lruMap.values.isEmpty, true); + }); + + test('`containsKey`如果键在映射中,则返回true', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.containsKey('A'), true); + expect(lruMap.containsKey('D'), false); + }); + + test('`containsValue`如果值在映射中,则返回true', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.containsValue('Alpha'), true); + expect(lruMap.containsValue('Delta'), false); + }); + + test('`forEach `返回所有键值对而不修改顺序', () { + final keys = []; + final values = []; + + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + expect(lruMap.values.toList(), ['Charlie', 'Beta', 'Alpha']); + + lruMap.forEach((key, value) { + keys.add(key); + values.add(value); + }); + + expect(keys, ['C', 'B', 'A']); + expect(values, ['Charlie', 'Beta', 'Alpha']); + expect(lruMap.keys.toList(), ['C', 'B', 'A']); + expect(lruMap.values.toList(), ['Charlie', 'Beta', 'Alpha']); + }); + + test('`获取条目`返回所有条目', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + var entries = lruMap.entries; + expect(entries, entries.length==3); + // MapEntry objects are not equal to each other; cannot use `contains`. :( + expect(entries.singleWhere((e) => e.key == 'A').value, 'Alpha'); + expect(entries.singleWhere((e) => e.key == 'B').value, 'Beta'); + expect(entries.singleWhere((e) => e.key == 'C').value, ('Charlie')); + }); + + test('addEntries将项目添加到开头', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + var entries = [const MapEntry('D', 'Delta'), const MapEntry('E', 'Echo')]; + lruMap.addEntries(entries); + expect(lruMap.keys.toList(), ['E', 'D', 'C', 'B', 'A']); + }); + + test('addEntries将现有项目添加到开头', () { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + + var entries = [const MapEntry('B', 'Bravo'), const MapEntry('E', 'Echo')]; + lruMap.addEntries(entries); + expect(lruMap.keys.toList(), ['E', 'B', 'C', 'A']); + }); + + test('重新添加标题条目是不可行的', () { + // See: https://github.com/google/quiver-dart/issues/357 + lruMap = LruMap(); + lruMap['A'] = 'Alpha'; + lruMap['A'] = 'Alpha'; + + expect(lruMap.keys.toList(), ['A']); + expect(lruMap.values.toList(), ['Alpha']); + }); + + group('`remove`', () { + // setUp(() { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + // }); + + test('返回与键关联的值(如果存在)', () { + expect(lruMap.remove('A'), 'Alpha'); + }); + + test('如果提供的密钥不存在,则返回null', () { + expect(lruMap.remove('D'), null); + }); + + test('可以移除最后一个项目(头部和尾部)', () { + // See: https://github.com/google/quiver-dart/issues/385 + lruMap = LruMap(maximumSize: 1) + ..addAll({'A': 'Alpha'}) + ..remove('A'); + lruMap['B'] = 'Beta'; + lruMap['C'] = 'Charlie'; + expect(lruMap.keys.toList(), ['C']); + }); + + test('可以删除头部', () { + lruMap.remove('C'); + expect(lruMap.keys.toList(), ['B', 'A']); + }); + + test('可以删除最后一项', () { + lruMap.remove('A'); + expect(lruMap.keys.toList(), ['C', 'B']); + }); + + test('可以删除中间条目', () { + lruMap.remove('B'); + expect(lruMap.keys.toList(), ['C', 'A']); + }); + + test('可以删除指定项', () { + lruMap.removeWhere((k, v) => v.contains('h')); + expect(lruMap.keys.toList(), ['B']); + }); + + test('可以批量删除', () { + lruMap.removeWhere((k, v) => v.contains('A')); + expect(lruMap.keys.toList(), ['C', 'B']); + }); + + test('删除时正确保留链接', () { + lruMap.remove('B'); + + // Order is now [C, A]. Trigger promotion of A to check linkage. + final _ = lruMap['A']; + + final keys = []; + lruMap.forEach((String k, String v) => keys.add(k)); + expect(keys, ['A', 'C']); + }); + }); + + test('当提升中间的项目时,链接列表会发生变化', () { + LruMap lruMap = LruMap(maximumSize: 3) + ..addAll({'C': 1, 'A': 1, 'B': 1}); + // Order is now [B, A, C]. Trigger promotion of A. + lruMap['A'] = 1; + + // Order is now [A, B, C]. Trigger promotion of C to check linkage. + final _ = lruMap['C']; + expect(lruMap.length, lruMap.keys.length); + expect(lruMap.keys.toList(), ['C', 'A', 'B']); + }); + + group('`putIfAbsent`', () { + // setUp(() { + lruMap = LruMap()..addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + // }); + + test('如果项目不存在,则添加该项目,并将其移动到MRU', () { + expect(lruMap.putIfAbsent('D', () => 'Delta'), 'Delta'); + expect(lruMap.keys.toList(), ['D', 'C', 'B', 'A']); + }); + + test('不添加项目(如果存在),但将其提升为MRU', () { + expect(lruMap.keys.toList(), ['B', 'C', 'A']); + }); + + test('如果超过“maximumSize”,则删除LRU项目', () { + lruMap.maximumSize = 3; + expect(lruMap.putIfAbsent('D', () => 'Delta'), 'Delta'); + expect(lruMap.keys.toList(), ['D', 'C', 'B']); + }); + + test('正确处理 maximumSize 1', () { + lruMap.maximumSize = 1; + lruMap.putIfAbsent('B', () => 'Beta'); + expect(lruMap.keys.toList(), ['B']); + }); + }); + }); + + group('LruMap builds an informative string representation', () { + late LruMap lruMap; + + // setUp(() { + lruMap = LruMap(); + // }); + + test('empty map', () { + expect(lruMap.toString(), '{}'); + }); + + test(' map 有一个值', () { + lruMap.addAll({'A': 'Alpha'}); + expect(lruMap.toString(), '{A: Alpha}'); + }); + + test('对于具有值的map', () { + lruMap.addAll({'A': 'Alpha', 'B': 'Beta', 'C': 'Charlie'}); + expect(lruMap.toString(), '{C: Charlie, B: Beta, A: Alpha}'); + }); + + test('可循环的map', () { + lruMap.addAll({'A': 'Alpha', 'B': lruMap}); + expect(lruMap.toString(), '{B: {...}, A: Alpha}'); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/collection/multimap_test.dart b/ohos/test_quiver/lib/src/collection/multimap_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1d33cd5dba6a4a7c07285618256d884b1a0758fa --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/multimap_test.dart @@ -0,0 +1,1057 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.multimap_test; + +import 'package:quiver/src/collection/multimap.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class MultimapTestPage extends TestPage { + MultimapTestPage(String title, { Key? key}) : super(title: title, key: key) { + group('Multimap', () { + test('列表支持的多映射', () { + var map = Multimap(); + expect(map is ListMultimap, true); + }); + }); + + group('Multimap.fromIterable', () { + var map = Multimap.fromIterable([1, 2, 1]); + expect(map.asMap(), { + 1: [1, 1], + 2: [2], + + }); + + + var i = 0; + var map1 = Multimap.fromIterable([1, 2, 1], + value: (x) => '$x:${i++}'); + expect(map1.asMap(), { + 1: ['1:0', '1:2'], + 2: ['2:1'], + + }); + + + var map2 = + Multimap.fromIterable([1, 2, 1], key: (x) => '($x)'); + expect(map2.asMap(), { + '(1)': [1, 1], + '(2)': [2], + }); + + + + var j = 0; + var map3 = Multimap.fromIterable([1, 2, 1], + key: (x) => -x, value: (x) => '$x:${j++}'); + expect(map3.asMap(), { + -1: ['1:0', '1:2'], + -2: ['2:1'], + }); + + }); + + group('Multimap asMap() view', () { + late Multimap mmap; + late Map> map; + + mmap = Multimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + map = mmap.asMap(); + + + test('operator[]=应抛出UnsupportedError', () { + map['k1'] = ['1', '2', '3']; + }); + + test('addEntries应抛出UnsupportedError', () { + map.addEntries(>>[] + ); + }); + + test('update 应抛出 UnsupportedError', () { + map.update('k1', (_) => ['1', '2', '3']) + ; + }); + + test('updateAll 应抛出 UnsupportedError', () { + map.updateAll((_, __) => ['1', '2', '3']); + }); + + test('containsKey() ', () { + expect(map.containsKey('k3'), false); + + expect(map.containsKey('k1'), true); + }); + + test('containsValue()', () { + expect(map.containsValue('k3'), false); + + expect(map.containsValue('v1'), true); + }); + + test('forEach应遍历所有键值对', () { + var results = []; + map.forEach((k, v) => results.add(Pair(k, v))); + expect( + results, + [ + Pair('k1', ['v1', 'v2']), + Pair('k2', ['v3']) + ]); + }); + + test( + 'isEmpty应返回映射是否包含键值对', () { + expect(map.isEmpty, false); + expect(map.isNotEmpty, true); + expect(Multimap() + .asMap() + .isEmpty, true); + expect(Multimap() + .asMap() + .isNotEmpty, false); + }); + + test('length应返回键值对的数量', () { + expect(Multimap() + .asMap() + .length, 0); + expect(map.length, 2); + }); + + // test('addAll(Map m) ', () { + // map.clear(); + // map.addAll(>{ + // 'k1': ['1', '2', '3'] + // }); + // }); + // + // test('putIfAbsent() ', () { + // var map = Multimap().asMap(); + // map.putIfAbsent('k1', () => [1]); + // }); + }); + + group('ListMultimap', () { + test('应初始化为空', () { + var map = ListMultimap(); + expect(map.isEmpty, true); + expect(map.isNotEmpty, false); + }); + + test('添加后不应为空', () { + var map = ListMultimap() + ..add('k', 'v'); + expect(map.isEmpty, false); + expect(map.isNotEmpty, true); + }); + + test('应将键数作为长度返回', () { + var map = ListMultimap(); + expect(map.length, 0); + map..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.length, 2); + }); + + test('应该为未映射的键返回一个空的可迭代项', () { + var map = ListMultimap(); + expect(map['k1'], []); + }); + + test('应支持为未映射的键添加值', () { + var map = ListMultimap() + ..['k1'] + .add('v1'); + expect(map['k1'], ['v1'] + ); + }); + + test('应支持为未映射的键添加多个值', () { + var map = ListMultimap() + ..['k1'] + .addAll(['v1', 'v2']); + expect(map['k1'], ['v1', 'v2'] + ); + }); + + test('应支持为未映射的键插入值', () { + var map = ListMultimap() + ..['k1'] + .insert(0, 'v1'); + expect(map['k1'], ['v1'] + ); + }); + + test('应支持为未映射的键插入多个值', () { + var map = ListMultimap() + ..['k1'] + .insertAll(0, ['v1', 'v2']); + expect(map['k1'], ['v1', 'v2'] + ); + }); + + test('应该支持增加未映射键的基础列表', () { + var map = ListMultimap() + ..['k1'] + .length = 2; + expect(map['k1'], [null, null]); + }); + + test('应返回在添加时保持同步的未映射迭代', () { + var map = ListMultimap(); + List values1 = map['k1']; + List values2 = map['k1']; + values1.add('v1'); + expect(map['k1'], ['v1']); + expect(values2, ['v1']); + }); + + test('应返回在addAll上保持同步的未映射迭代', () { + var map = ListMultimap(); + List values1 = map['k1']; + List values2 = map['k1']; + values1.addAll(['v1', 'v2']); + expect(map['k1'], ['v1', 'v2']); + expect(values2, ['v1', 'v2']); + }); + + test('应该支持为键添加重复值', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v1'); + expect(map['k'], ['v1', 'v1']); + }); + + test( + '应支持在初始化时为键添加重复值', () { + var map = ListMultimap.fromIterable(['k', 'k'], + value: (x) => 'v1'); + expect(map['k'], ['v1', 'v1']); + }); + + test('应支持添加多个密钥', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test('应支持同时添加多个值', () { + var map = ListMultimap() + ..addValues('k1', ['v1', 'v2']); + expect(map['k1'], ['v1', 'v2']); + }); + + test( + '应支持为现有键同时添加多个值', () { + var map = ListMultimap() + ..add('k1', 'v1') + ..addValues('k1', ['v1', 'v2']); + expect(map['k1'], ['v1', 'v1', 'v2']); + }); + + test('应该支持从另一个map添加', () { + var from = ListMultimap() + ..addValues('k1', ['v1', 'v2']) + ..add('k2', 'v3'); + var map = ListMultimap() + ..addAll(from); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test( + '应该支持使用现有键从另一个多映射添加', () { + var from = ListMultimap() + ..addValues('k1', ['v1', 'v2']) + ..add('k2', 'v3'); + var map = ListMultimap() + ..add('k1', 'v0')..add('k2', 'v3') + ..addAll(from); + expect(map['k1'], ['v0', 'v1', 'v2']); + expect(map['k2'], ['v3', 'v3']); + }); + + test('应返回其密钥', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.keys, ['k1', 'k2']); + }); + + test('应返回其值', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.values, ['v1', 'v2', 'v3']); + }); + + test('应支持重复的值', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v1'); + expect(map.values, ['v1', 'v2', 'v1']); + }); + + test('应返回一个有序的值列表', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map['k'], ['v1', 'v2']); + }); + + test('应反映对基础列表的更改', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v2'); + map['k'].add('v3'); + map['k'].remove('v2'); + expect(map['k'], ['v1', 'v3']); + }); + + test('应返回是否包含密钥', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map.containsKey('j'), false); + expect(map.containsKey('k'), true); + }); + + test('应返回是否包含值', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map.containsValue('v0'), false); + expect(map.containsValue('v1'), true); + }); + + test('应返回是否包含键/值关联', () { + var map = ListMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map.contains('k', 'v0'), false); + expect(map.contains('f', 'v1'), false); + expect(map.contains('k', 'v1'), true); + }); + + test('应删除指定的键值关联', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.remove('k1', 'v0'), false); + expect(map.remove('k1', 'v1'), true); + expect(map['k1'], ['v2']); + expect(map.containsKey('k2'), true); + }); + + test('应在删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1') + ..remove('k1', 'v1'); + expect(map.containsKey('k1'), false); + }); + + test( + '应在删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].remove('v1'); + expect(map.containsKey('k1'), false); + }); + + test( + '应在删除所有关联值时删除键,通过基础iterable.removeAt', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].removeAt(0); + expect(map.containsKey('k1'), false); + }); + + test( + '应在从底层iterable.removeAt中删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].removeLast(); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.removeRange删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].removeRange(0, 1); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.removeWhere删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].removeWhere((_) => true); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.replaceRange删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].replaceRange(0, 1, []); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.retainWhere删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1'); + map['k1'].retainWhere((_) => false); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.clear删除所有关联值时删除键', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + map['k1'].clear(); + expect(map.containsKey('k1'), false); + }); + + test('应删除键的所有值', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.removeAll('k1'), ['v1', 'v2']); + expect(map.containsKey('k1'), false); + expect(map.containsKey('k2'), true); + }); + + test('应使用所有{key,value}对调用removeWhere', () { + Set s = {}; + ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..removeWhere((k, v) { + s.add(Pair(k, v)); + return false; + }); + expect( + s, + + [Pair('k1', 'v1'), Pair('k1', 'v2'), Pair('k2', 'v3')]); + }); + + test( + '应删除所有满足removeWhere中谓词的{key,value}对', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v1') + ..removeWhere((k, v) => k == 'k2' || v == 'v1'); + expect(map.keys, ['k1']); + expect(map.values, ['v2']); + }); + + test('应在移除时清除底层iterable', () { + var map = ListMultimap() + ..add('k1', 'v1'); + List values = map['k1']; + expect(map.removeAll('k1'), ['v1']); + expect(values, []); + }); + + test('应在removeAll of unmapped键上返回一个空的iterable', () { + var map = ListMultimap(); + var removed = map.removeAll('k1'); + expect(removed, []); + }); + + test('应与removeAll返回的iterable解耦', () { + var map = ListMultimap() + ..add('k1', 'v1'); + var removed = map.removeAll('k1'); + removed.add('v2'); + map.add('k1', 'v3'); + expect(removed, ['v1', 'v2']); + expect(map['k1'], ['v3']); + }); + + test('应该清除map', () { + var map = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..clear(); + expect(map.isEmpty, true); + expect(map.containsKey('k1'), false); + expect(map.containsKey('k2'), false); + }); + + test('应清除clear上的底层iterable', () { + var map = ListMultimap() + ..add('k1', 'v1'); + List values = map['k1']; + map.clear(); + expect(values, []); + }); + + test('不应在查找未映射的键时添加映射', () { + var map = ListMultimap() + ..['k1']; + expect(map.containsKey('k1'), false); + }); + + test('不应在清除映射值时删除映射', () { + var map = ListMultimap() + ..add('k1', 'v1') + ..['v1'] + .clear(); + expect(map.containsKey('k1') + , + true + ); + }); + + test('应返回map', () { + var mmap = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + Map map = mmap.asMap(); + expect(map.keys, ['k1', 'k2']); + expect(map.values, map.values.length == 2); + expect(map.values, ['v1', 'v2']); + expect(map.values, ['v3']); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test('应在映射视图上返回一个空的可迭代未映射键', () { + Map map = ListMultimap().asMap(); + expect(map['k1'], []); + }); + + test('应允许通过映射视图上的未映射键查找进行添加', () { + var mmap = ListMultimap(); + Map map = mmap.asMap(); + map['k1'].add('v1'); + map['k2'].addAll(['v1', 'v2']); + expect(mmap['k1'], ['v1']); + expect(mmap['k2'], ['v1', 'v2']); + }); + + test('应反映映射视图返回的可迭代项的添加', () { + var mmap = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + map['k1'].add('v3'); + expect(mmap['k1'], ['v1', 'v2', 'v3']); + }); + + test('应反映返回的map中键的删除', () { + var mmap = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + map.remove('k1'); + expect(mmap.containsKey('k1'), false); + }); + + test('应反映清除返回的地图视图', () { + var mmap = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + Map map = mmap.asMap(); + map.clear(); + expect(mmap.isEmpty, true); + }); + + test('应支持对所有{key,value}对进行迭代', () { + Set s = {}; + ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..forEach((k, v) => s.add(Pair(k, v))); + expect( + s, + + [Pair('k1', 'v1'), Pair('k1', 'v2'), Pair('k2', 'v3')]); + }); + + test( + '应支持对所有{key,Iterable<value>}对进行迭代', () { + Map map = {}; + var mmap = ListMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..forEachKey((k, v) => map[k] = v); + expect(map.length, mmap.length); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test( + '应支持在不中断委托同步的情况下对空映射视图执行操作', + () { + var mmap = ListMultimap(); + List x = mmap['k1']; + List y = mmap['k1']; + List z = mmap['k1']; + List w = mmap['k1']; + mmap['k1'].add('v1'); + expect(mmap['k1'], ['v1']); + x.add('v2'); + expect(mmap['k1'], ['v1', 'v2']); + y.addAll(['v3', 'v4']); + expect(mmap['k1'], ['v1', 'v2', 'v3', 'v4']); + z.insert(0, 'v0'); + expect(mmap['k1'], ['v0', 'v1', 'v2', 'v3', 'v4']); + w.insertAll(5, ['v5', 'v6']); + expect(mmap['k1'], ['v0', 'v1', 'v2', 'v3', 'v4', 'v5', 'v6']); + }); + }); + + group('SetMultimap', () { + test('应初始化为空', () { + var map = SetMultimap(); + expect(map.isEmpty, true); + expect(map.isNotEmpty, false); + }); + + test('添加后不应为空', () { + var map = SetMultimap() + ..add('k', 'v'); + expect(map.isEmpty, false); + expect(map.isNotEmpty, true); + }); + + test('应将键数作为长度返回', () { + var map = SetMultimap(); + expect(map.length, 0); + map..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.length, 2); + }); + + test('应该为未映射的键返回一个空的可迭代项', () { + var map = SetMultimap(); + expect(map['k1'], []); + }); + + test('应支持为未映射的键添加值', () { + var map = SetMultimap() + ..['k1'] + .add('v1'); + expect(map['k1'], ['v1'] + ); + }); + + test('应支持为未映射的键添加多个值', () { + var map = SetMultimap() + ..['k1'] + .addAll(['v1', 'v2']); + expect(map['k1'], ['v1', 'v2'] + ); + }); + + test('应返回在添加时保持同步的未映射迭代', () { + var map = SetMultimap(); + Set values1 = map['k1']; + Set values2 = map['k1']; + values1.add('v1'); + expect(map['k1'], ['v1']); + expect(values2, ['v1']); + }); + + test('应返回在addAll上保持同步的未映射迭代', () { + var map = SetMultimap(); + Set values1 = map['k1']; + Set values2 = map['k1']; + values1.addAll(['v1', 'v2']); + expect(map['k1'], ['v1', 'v2']); + expect(values2, ['v1', 'v2']); + }); + + test('不应支持为键添加重复值', () { + var map = SetMultimap() + ..add('k', 'v1')..add('k', 'v1'); + expect(map['k'], ['v1']); + }); + + test( + '当从可迭代项初始化时,不应支持为键添加重复值', () { + var map = SetMultimap.fromIterable(['k', 'k'], + value: (x) => 'v1'); + expect(map['k'], ['v1']); + }); + + test('应支持添加多个密钥', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test('应支持同时添加多个值', () { + var map = SetMultimap() + ..addValues('k1', ['v1', 'v2']); + expect(map['k1'], ['v1', 'v2']); + }); + + test( + '应支持为现有键同时添加多个值', () { + var map = SetMultimap() + ..add('k1', 'v0') + ..addValues('k1', ['v1', 'v2']); + expect(map['k1'], ['v0', 'v1', 'v2']); + }); + + test( + '应支持为现有(键、值)添加多个值', () { + var map = SetMultimap() + ..add('k1', 'v1') + ..addValues('k1', ['v1', 'v2']); + expect(map['k1'], ['v1', 'v2']); + }); + + test('应该支持从另一个多映射添加', () { + var from = SetMultimap() + ..addValues('k1', ['v1', 'v2']) + ..add('k2', 'v3'); + var map = SetMultimap() + ..addAll(from); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test( + '应该支持使用现有键从另一个多映射添加', () { + var from = SetMultimap() + ..addValues('k1', ['v1', 'v2']) + ..add('k2', 'v3'); + var map = SetMultimap() + ..add('k1', 'v0')..add('k2', 'v3') + ..addAll(from); + expect(map['k1'], ['v0', 'v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test('应返回其密钥', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.keys, ['k1', 'k2']); + }); + + test('应返回其值', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.values, ['v1', 'v2', 'v3']); + }); + + test('应支持重复的值', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v1'); + expect(map.values, ['v1', 'v2', 'v1']); + }); + + test('应返回一个有序的值列表', () { + var map = SetMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map['k'], ['v1', 'v2']); + }); + + test('应反映对基础集的更改', () { + var map = SetMultimap() + ..add('k', 'v1')..add('k', 'v2'); + map['k'].add('v3'); + map['k'].remove('v2'); + expect(map['k'], ['v1', 'v3']); + }); + + test('应返回是否包含密钥', () { + var map = SetMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map.containsKey('j'), false); + expect(map.containsKey('k'), true); + }); + + test('应返回是否包含值', () { + var map = SetMultimap() + ..add('k', 'v1')..add('k', 'v2'); + expect(map.containsValue('v0'), false); + expect(map.containsValue('v1'), true); + }); + + test('应删除指定的键值关联', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.remove('k1', 'v0'), false); + expect(map.remove('k1', 'v1'), true); + expect(map['k1'], ['v2']); + expect(map.containsKey('k2'), true); + }); + + test('应在删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1') + ..remove('k1', 'v1'); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.remove删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1'); + map['k1'].remove('v1'); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.removeAll删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + map['k1'].removeAll(['v1', 'v2']); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.removeWhere删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1'); + map['k1'].removeWhere((_) => true); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.reainAll删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1'); + map['k1'].retainAll([]); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.retainWhere删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1'); + map['k1'].retainWhere((_) => false); + expect(map.containsKey('k1'), false); + }); + + test( + '应在通过底层iterable.clear删除所有关联值时删除键', () { + var map = SetMultimap() + ..add('k1', 'v1'); + map['k1'].clear(); + expect(map.containsKey('k1'), false); + }); + + test('应删除键的所有值', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + expect(map.removeAll('k1'), ['v1', 'v2']); + expect(map.containsKey('k1'), false); + expect(map.containsKey('k2'), true); + }); + + test('应使用所有{key,value}对调用removeWhere', () { + Set s = {}; + SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..removeWhere((k, v) { + s.add(Pair(k, v)); + return false; + }); + expect( + s, + + [Pair('k1', 'v1'), Pair('k1', 'v2'), Pair('k2', 'v3')]); + }); + + test( + '应删除所有满足removeWhere中谓词的{key,value}对', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v1') + ..removeWhere((k, v) => k == 'k2' || v == 'v1'); + expect(map.keys, ['k1']); + expect(map.values, ['v2']); + }); + + test('应在移除时清除底层可迭代项', () { + var map = SetMultimap() + ..add('k1', 'v1'); + Set values = map['k1']; + expect(map.removeAll('k1'), ['v1']); + expect(values, []); + }); + + test('应在removeAll of unmapped键上返回一个空的可迭代项', () { + var map = SetMultimap(); + var removed = map.removeAll('k1'); + expect(removed, []); + }); + + test('应与removeAll返回的可迭代项解耦', () { + var map = SetMultimap() + ..add('k1', 'v1'); + var removed = map.removeAll('k1'); + removed.add('v2'); + map.add('k1', 'v3'); + expect(removed, ['v1', 'v2']); + expect(map['k1'], ['v3']); + }); + + test('应该清除地图', () { + var map = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..clear(); + expect(map.isEmpty, true); + expect(map.containsKey('k1'), false); + expect(map.containsKey('k2'), false); + }); + + test('应清除clear上的底层可迭代项', () { + var map = SetMultimap() + ..add('k1', 'v1'); + Set values = map['k1']; + map.clear(); + expect(values, []); + }); + + test('不应在查找未映射的键时添加映射', () { + var map = SetMultimap() + ..['k1']; + expect(map.containsKey('k1'), false); + }); + + test('不应在清除映射值时删除映射', () { + var map = SetMultimap() + ..add('k1', 'v1') + ..['v1'] + .clear(); + expect(map.containsKey('k1') + , + true + ); + }); + + test('应返回地图视图', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + Map map = mmap.asMap(); + expect(map.keys, ['k1', 'k2']); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test('应在映射视图上返回一个空的可迭代未映射键', () { + Map map = SetMultimap().asMap(); + expect(map['k1'], []); + }); + + test('应允许通过映射视图上的未映射键查找进行添加', () { + var mmap = SetMultimap(); + Map map = mmap.asMap(); + map['k1'].add('v1'); + map['k2'].addAll(['v1', 'v2']); + expect(mmap['k1'], ['v1']); + expect(mmap['k2'], ['v1', 'v2']); + }); + + test('应反映映射视图返回的可迭代项的添加', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + map['k1'].add('v3'); + expect(mmap['k1'], ['v1', 'v2', 'v3']); + }); + + test('应反映映射视图返回的可迭代项的添加', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + map['k1'].add('v3'); + expect(mmap['k1'], ['v1', 'v2', 'v3']); + }); + + test('应反映返回的映射视图中键的删除', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + map.remove('k1'); + expect(mmap.containsKey('k1'), false); + }); + + test('是否应该了解返回的映射视图中的条目', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + expect(map.entries, map.entries.length == 1); + expect(map.entries.single.key, 'k1'); + expect(map.entries.single.value, ['v1', 'v2']); + }); + + test('应该从返回的地图视图映射', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2'); + Map map = mmap.asMap(); + var newMap = map.map((k, v) => MapEntry(k, v.join(','))); + expect(newMap, newMap.length == 1); + expect(newMap, newMap.containsKey('k1')); + expect(newMap, newMap.containsValue('v1,v2')); + }); + + test('应反映清除返回的地图视图', () { + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3'); + Map map = mmap.asMap(); + map.clear(); + expect(mmap.isEmpty, true); + }); + + test('应支持对所有{key,value}对进行迭代', () { + Set s = {}; + SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..forEach((k, v) => s.add(Pair(k, v))); + expect( + s, + + [Pair('k1', 'v1'), Pair('k1', 'v2'), Pair('k2', 'v3')]); + }); + + test( + '应支持对所有{key,Iterable<value>}对进行迭代', () { + Map map = {}; + var mmap = SetMultimap() + ..add('k1', 'v1')..add('k1', 'v2')..add('k2', 'v3') + ..forEachKey((k, v) => map[k] = v); + expect(map.length, mmap.length); + expect(map['k1'], ['v1', 'v2']); + expect(map['k2'], ['v3']); + }); + + test( + '应支持在不中断委托同步的情况下对空映射视图执行操作', () { + var mmap = SetMultimap(); + Set x = mmap['k1']; + Set y = mmap['k1']; + mmap['k1'].add('v0'); + x.add('v1'); + y.addAll(['v2', 'v3']); + expect(mmap['k1'], ['v0', 'v1', 'v2', 'v3']); + }); + }); + } +} + +class Pair { + Pair(this.x, this.y) : assert(x != null && y != null); + + final T x; + final T y; + + @override + bool operator ==(Object other) { + if (other is! Pair) return false; + if (x != other.x) return false; + return y == other.y; + } + + @override + int get hashCode => x.hashCode ^ y.hashCode; + + @override + String toString() => '($x, $y)'; +} diff --git a/ohos/test_quiver/lib/src/collection/treeset_test.dart b/ohos/test_quiver/lib/src/collection/treeset_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..89da5682bb96cea08dcab8ee8868688a5603562c --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/treeset_test.dart @@ -0,0 +1,583 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.treeset_test; + +import 'package:quiver/src/collection/treeset.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; +import 'package:matcher/src/expect/throws_matcher.dart'; + +/// Matcher that verifies an [Error] is thrown. + +class TreeSetTestPage extends TestPage { + TreeSetTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('TreeSet', () { + group('when empty', () { + late TreeSet tree; + // setUp(() { + tree = TreeSet(); + // }); + test('TreeSet.isEmpty', () => expect(tree.isEmpty, tree.isEmpty)); + test('不应包含元素', + () => expect(tree.lookup(0), null)); + test('向前迭代时没有元素', () { + var i = tree.iterator; + expect(i.moveNext(), false); + expect(() => i.current, null); + }); + test('向后迭代时没有元素', () { + var i = tree.iterator; + expect(i.movePrevious(), false); + expect(() => i.current, null); + }); + }); + + group('with [10, 20, 15]', () { + late AvlTreeSet tree; + + tree = TreeSet() as AvlTreeSet; + tree.addAll([10, 20, 15]); + + test('查找插入的元素成功', () { + expect(tree.lookup(10), 10); + expect(tree.lookup(15), 15); + expect(tree.lookup(20), 20); + }); + test('订单是正确的', () { + AvlNode ten = debugGetNode(tree, 10)!; + AvlNode twenty = debugGetNode(tree, 20)!; + AvlNode fifteen = debugGetNode(tree, 15)!; + expect(ten.predecessor, null ); + expect(ten.successor, fifteen); + expect(ten.successor!.successor, twenty + ); + + expect(twenty.successor, null,); + expect(twenty.predecessor, fifteen); + expect(twenty.predecessor!.predecessor, ten); + }); + }); + + group('First & Last', () { + test(' num ', () { + var tree = TreeSet(); + tree.add(1); + tree.add(2); + tree.add(3); + expect(tree.first, 1); + expect(tree.last, 3); + }); + + test(' String ', () { + var tree = TreeSet(); + tree.add('abc'); + tree.add('aaa'); + tree.add('zzz'); + expect(tree.first, 'aaa'); + expect(tree.last, 'zzz'); + }); + }); + + group('with repeated elements', () { + late TreeSet tree; + + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + + + test('仅包含子集', () { + var it = tree.iterator; + var testList = List.from([10, 15, 20, 21, 30]); + while (it.moveNext()) { + expect(it.current, testList.removeAt(0)); + } + expect(testList.length, 0); + }); + }); + + group('iteration', () { + late TreeSet tree; + + tree = TreeSet()..addAll([10, 20, 15, 21, 30]); + + + test('双向工作', () { + var it = tree.iterator; + while (it.moveNext()) {} + expect(it.movePrevious(), true + ); + expect(it.current, 30 + ); + while (it.movePrevious()) {} + expect(it.moveNext(), true + ); + expect(it.current, 10, + ); + }); + + group('from', () { + test('未插入中点向前工作', () { + var it = tree.fromIterator(19); + expect(() => it.current, null); + expect(it.moveNext(), true,); + expect(it.current, 20); + }); + + test('movePrevious()', () { + var it = tree.fromIterator(19); + expect(() => it.current, null); + expect(it.movePrevious(), true); + expect(it.current, 15); + }); + + test('reversed', () { + var it = tree.fromIterator(19, reversed: true); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 15); + }); + + test(' reversed, movePrevious()', () { + var it = tree.fromIterator(19, reversed: true); + expect(() => it.current, null); + expect(it.movePrevious(), true + ); + expect(it.current, 20); + }); + + test('插入的中点向前工作', () { + var it = tree.fromIterator(20); + expect(() => it.current, null); + expect(it.moveNext(), true,); + expect(it.current, 20); + }); + + test('插入的中点反向工作', () { + var it = tree.fromIterator(20, reversed: true); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 20); + }); + + test('set后', () { + var it = tree.fromIterator(100); + expect(() => it.current, null); + expect(it.moveNext(), false); + expect(it.movePrevious(), true); + expect(it.current, 30); + }); + + test('set之前', () { + var it = tree.fromIterator(0); + expect(() => it.current, null); + expect(it.movePrevious(), false); + expect(it.moveNext(), true); + expect(it.current, 10); + }); + + test('inserted midpoint, non-inclusive, works forward', () { + var it = tree.fromIterator(20, inclusive: false); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 21); + }); + + test('inserted endpoint, non-inclusive, works forward', () { + var it = tree.fromIterator(30, inclusive: false); + expect(() => it.current, null); + expect(it.moveNext(), false); + + it = tree.fromIterator(10, inclusive: false); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 15); + }); + + test('inserted endpoint, non-inclusive, works backward', () { + var it = tree.fromIterator(10, inclusive: false); + expect(() => it.current, null); + expect(it.movePrevious(), false + ); + + it = tree.fromIterator(30, inclusive: false); + expect(() => it.current, null); + expect(it.movePrevious(), true + ); + expect(it.current, 21); + }); + + test('inserted midpoint, non-inclusive, reversed, works forward', () { + var it = tree.fromIterator(20, inclusive: false, reversed: true); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 15); + }); + + test('inserted endpoint, non-inclusive, reversed, works forward', () { + var it = tree.fromIterator(30, inclusive: false, reversed: true); + expect(() => it.current, null); + expect(it.moveNext(), true); + expect(it.current, 21); + + it = tree.fromIterator(10, inclusive: false, reversed: true); + expect(() => it.current, null); + expect(it.moveNext(), false); + }); + + test('inserted endpoint, non-inclusive, reversed, works backward', () { + var it = tree.fromIterator(10, inclusive: false, reversed: true); + expect(() => it.current, null); + expect(it.movePrevious(), true + ); + expect(it.current, 15); + + it = tree.fromIterator(30, inclusive: false, reversed: true); + expect(() => it.current, null); + expect(it.movePrevious(), false + ); + }); + }); + + group('fails', () { + late Iterator it; + // setUp(() { + it = tree.iterator; + // }); + + test('清除树之后', () { + tree.clear(); + dynamic error; + try { + it.moveNext(); + } catch (e) { + error = e; + } + expect(error, null); + }); + + test('插入元素后', () { + tree.add(101); + dynamic error; + try { + it.moveNext(); + } catch (e) { + error = e; + } + expect(error, null); + }); + + test('删除元素后', () { + tree.remove(10); + dynamic error; + try { + it.moveNext(); + } catch (e) { + error = e; + } + expect(error,null); + }); + }); + + group('still works', () { + late Iterator it; + // setUp(() { + it = tree.iterator; + // }); + + test('删除不存在的元素时', () { + tree.remove(42); + dynamic error; + try { + it.moveNext(); + } catch (e) { + error = e; + } + expect(error, null); + }); + test('添加已存在的元素时', () { + tree.add(10); + dynamic error; + try { + it.moveNext(); + } catch (e) { + error = e; + } + expect(error, null); + }); + }); + }); + + group('removal', () { + late TreeSet tree; + + test('从空树中删除', () { + tree = TreeSet(); + tree.remove(10); + expect(tree, tree.isEmpty); + }); + + test('从树中删除', () { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + tree.remove(42); + expect(tree.toList(), [10, 15, 20, 21, 30]); + + tree.remove(10); + expect(tree.toList(), [15, 20, 21, 30]); + + tree.remove(30); + expect(tree.toList(), [15, 20, 21]); + + tree.remove(20); + expect(tree.toList(), [15, 21]); + }); + + test('removeAll', () { + tree = TreeSet() + ..addAll([1, 3, 5, 6, 2, 4]) + ..removeAll([1, 3]); + expect(tree.toList(), [2, 4, 5, 6]); + }); + + test('removeAll from tree', () { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + tree.removeAll([42]); + expect(tree.toList(),[10, 15, 20, 21, 30]); + + tree.removeAll([10, 30]); + expect(tree.toList(), [15, 20, 21]); + + tree.removeAll([21, 20, 15]); + expect(tree, tree.isEmpty); + }); + + test('removeWhere from tree', () { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + tree.removeWhere((e) => e % 10 == 2); + expect(tree.toList(), [10, 15, 20, 21, 30]); + + tree.removeWhere((e) => e % 10 == 0); + expect(tree.toList(), [15, 21]); + + tree.removeWhere((e) => e % 10 > 0); + expect(tree, tree.isEmpty); + }); + + test('retainAll from tree', () { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + tree.retainAll([10, 30]); + expect(tree.toList(), [10, 30]); + + tree.retainAll([42]); + expect(tree, tree.isEmpty); + }); + + test('retainWhere from tree', () { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + tree.retainWhere((e) => e % 1 == 0); + expect(tree.toList(), [10, 15, 20, 21, 30]); + + tree.retainWhere((e) => e % 10 == 0); + expect(tree.toList(), [10, 20, 30]); + + tree.retainWhere((e) => e % 10 > 0); + expect(tree, tree.isEmpty); + }); + }); + + group('set math', () { + /// NOTE: set math with sorted sets should have a performance benefit; + /// we do not check the performance, only that the resulting math + /// is equivalent to non-sorted sets. + + late TreeSet tree; + late List expectedUnion; + late List expectedIntersection; + late List expectedDifference; + late Set nonSortedTestSet; + late TreeSet sortedTestSet; + + // setUp(() { + tree = TreeSet()..addAll([10, 20, 15, 21, 30, 20]); + expectedUnion = [10, 15, 18, 20, 21, 22, 30]; + expectedIntersection = [10, 15]; + expectedDifference = [20, 21, 30]; + nonSortedTestSet = {10, 18, 22, 15}; + sortedTestSet = TreeSet()..addAll(nonSortedTestSet); + // }); + + test( + '具有非排序集的并集', + () => expect( + tree.union(nonSortedTestSet).toList(), expectedUnion)); + test( + '具有排序集的并集', + () => expect( + tree.union(sortedTestSet).toList(), expectedUnion)); + test( + '与非排序集的交集', + () => expect(tree.intersection(nonSortedTestSet).toList(), + expectedIntersection)); + test( + '与排序集的交集', + () => expect(tree.intersection(sortedTestSet).toList(), + expectedIntersection)); + test( + '与非排序集的差异', + () => expect(tree.difference(nonSortedTestSet).toList(), + expectedDifference)); + test( + '排序集的差异', + () => expect(tree.difference(sortedTestSet).toList(), + expectedDifference)); + }); + + group('AVL implementation', () { + /// NOTE: This is implementation specific testing for coverage. + /// Users do not have access to [AvlNode] or [AvlTreeSet] + test('RightLeftRotation', () { + AvlTreeSet tree = TreeSet() as AvlTreeSet; + tree.add(10); + tree.add(20); + tree.add(15); + + AvlNode ten = debugGetNode(tree, 10)!; + AvlNode twenty = debugGetNode(tree, 20)!; + AvlNode fifteen = debugGetNode(tree, 15)!; + + expect(ten.parent, fifteen); + expect(ten.hasLeft, false); + expect(ten.hasRight, false); + expect(ten.balance, 0); + + expect(twenty.parent, fifteen); + expect(twenty.hasLeft, false); + expect(twenty.hasRight, false); + expect(twenty.balance, 0); + + expect(fifteen.hasParent, false); + expect(fifteen.left, ten); + expect(fifteen.right, twenty); + expect(fifteen.balance, 0); + }); + test('左右旋转', () { + AvlTreeSet tree = TreeSet() as AvlTreeSet; + tree.add(30); + tree.add(10); + tree.add(20); + + AvlNode thirty = debugGetNode(tree, 30)!; + AvlNode ten = debugGetNode(tree, 10)!; + AvlNode twenty = debugGetNode(tree, 20)!; + + expect(thirty.parent, twenty); + expect(thirty.hasLeft, false); + expect(thirty.hasRight, false); + expect(thirty.balance, 0); + + expect(ten.parent, twenty); + expect(ten.hasLeft, false); + expect(ten.hasRight, false); + expect(ten.balance, 0); + + expect(twenty.hasParent, false); + expect(twenty.left, ten); + expect(twenty.right, thirty); + expect(twenty.balance, 0); + }); + + test('AVL向左旋转', () { + AvlTreeSet tree = TreeSet() as AvlTreeSet; + tree.add(1); + tree.add(2); + tree.add(3); + + AvlNode one = debugGetNode(tree, 1)!; + AvlNode two = debugGetNode(tree, 2)!; + AvlNode three = debugGetNode(tree, 3)!; + + expect(one.parent, two); + expect(one.hasLeft, false); + expect(one.hasRight, false); + expect(one.balance, 0); + + expect(three.parent, two); + expect(three.hasLeft, false); + expect(three.hasRight, false); + expect(three.balance, 0); + + expect(two.hasParent, false); + expect(two.left, one); + expect(two.right, three); + expect(two.balance, 0); + }); + + test('AVL向右旋转', () { + AvlTreeSet tree = TreeSet() as AvlTreeSet; + tree.add(3); + tree.add(2); + tree.add(1); + + AvlNode one = debugGetNode(tree, 1)!; + AvlNode two = debugGetNode(tree, 2)!; + AvlNode three = debugGetNode(tree, 3)!; + + expect(one.parent, two); + expect(one.hasLeft, false); + expect(one.hasRight, false); + expect(one.balance, 0); + + expect(three.parent, two); + expect(three.hasLeft, false); + expect(three.hasRight, false); + expect(three.balance, 0); + + expect(two.hasParent, false); + expect(two.left, one); + expect(two.right, three); + expect(two.balance, 0); + }); + }); + + group('nearest search', () { + late TreeSet tree; + // setUp(() { + tree = TreeSet(comparator: (num left, num right) { + return left - right as int; + }) + ..addAll([300, 200, 100]); + // }); + + test('最近的', () { + var val = tree.nearest(199); + expect(val, 200); + val = tree.nearest(201); + expect(val, 200); + val = tree.nearest(150); + expect(val,100); + }); + + test('小于', () { + var val = tree.nearest(199, nearestOption: TreeSearch.LESS_THAN); + expect(val, 100); + }); + + test('大于', () { + var val = tree.nearest(101, nearestOption: TreeSearch.GREATER_THAN); + expect(val, 200); + }); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/collection/utils_test.dart b/ohos/test_quiver/lib/src/collection/utils_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..826169362b127f144e5423b0de5268db166e0934 --- /dev/null +++ b/ohos/test_quiver/lib/src/collection/utils_test.dart @@ -0,0 +1,84 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.collection.utils_test; + +import 'dart:io'; + +import 'package:quiver/src/collection/utils.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CollectionUtilsTestPage extends TestPage { + CollectionUtilsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('listsEqual', () { + test('对于相等列表,返回true', () { + expect(listsEqual(null, null), true); + expect(listsEqual([], []), true); + expect(listsEqual([1], [1]), true); + expect(listsEqual(['a', 'b'], ['a', 'b']), true); + }); + + test('对于不相等的列表,返回false', () { + expect(listsEqual(null, []), false); + expect(listsEqual([], null), false); + expect(listsEqual([1], [2]), false); + expect(listsEqual([1], []), false); + expect(listsEqual([], [1]), false); + }); + }); + + group('listMap', () { + test('对于相等的映射返回true', () { + expect(mapsEqual({}, {}), true); + expect(mapsEqual({'a': 1}, {'a': 1}), true); + }); + + test('对于不等映射,返回false', () { + expect(mapsEqual({'a': 1}, {'a': 2}), false); + expect(mapsEqual({'a': 1}, {'b': 1}), false); + expect(mapsEqual({'a': 1}, {'a': 1, 'b': 2}), false); + expect(mapsEqual({'a': 1, 'b': 2}, {'a': 1}), false); + }); + }); + + group('setsEqual', () { + test('对于相等集返回true', () { + expect(setsEqual({}, {}), true); + expect(setsEqual({1}, {1}), true); + expect(setsEqual({'a', 'b'}, {'a', 'b'}), true); + }); + + test('不相等集合返回false', () { + expect(setsEqual({1}, {2}), false); + expect(setsEqual({1}, {}), false); + expect(setsEqual({}, {1}), false); + }); + }); + + group('indexOf', () { + test('返回第一个匹配索引', () { + expect(indexOf([1, 12, 19, 20, 24], (n) => n % 2 == 0), 1); + expect(indexOf(['a', 'b', 'a'], (s) => s == 'a'), 0); + }); + + test('当没有匹配项时返回-1', () { + expect(indexOf([1, 3, 7], (n) => n % 2 == 0), -1); + expect(indexOf(['a', 'b'], (s) => s == 'e'), -1); + expect(indexOf([], (_) => true), -1); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/core/hash_test.dart b/ohos/test_quiver/lib/src/core/hash_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d3badd058b894cffbd194e9976a29b36876244dd --- /dev/null +++ b/ohos/test_quiver/lib/src/core/hash_test.dart @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.core.hash_test; + +import 'dart:math'; + +import 'package:quiver/src/core/hash.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class HashTestPage extends TestPage { + HashTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('hashObjects应返回int', () { + int h = hashObjects(['123', 456]); + expect(h,h); + h; + }); + + test('hashObjects应返回null', () { + int h = hashObjects(['123', null]); + h; + }); + + test('hashObjects应该处理所有为null的对象', () { + int h = hashObjects([null, null]); + h; + }); + + test('hash2应该返回一个int', () { + int h = hash2('123', 456); + h; + }); + + test('hash3应该返回一个int', () { + int h = hash3('123', 456, true); + h; + }); + + test('hash4应该返回一个int', () { + int h = hash4('123', 456, true, []); + h; + }); + } +} diff --git a/ohos/test_quiver/lib/src/core/optional_test.dart b/ohos/test_quiver/lib/src/core/optional_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..827a0cdd8981c6da65da882847569c6f20f3e4d8 --- /dev/null +++ b/ohos/test_quiver/lib/src/core/optional_test.dart @@ -0,0 +1,158 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// ignore_for_file: deprecated_member_use_from_same_package +library quiver.core.optional_test; + +import 'package:quiver/src/core/optional.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class OptionalTestPage extends TestPage { + OptionalTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('Optional', () { + test('absent不存在‘', () { + const Optional absent = Optional.absent(); + expect(absent.isPresent, false); + expect(absent.isNotPresent, true); + }); + + test('应存在并返回值', () { + Optional seven = Optional.of(7); + expect(seven.isPresent, true); + expect(seven.isNotPresent, false); + expect(seven.value, 7); + }); + + test('ifPresent应仅在存在时执行', () { + int? value; + Optional.of(7).ifPresent((v) { + value = v; + }); + expect(value, 7); + const Optional.absent().ifPresent((v) { + value = v; + }); + expect(value, 7); + }); + + test('sAbsent应仅在不存在时执行', () { + int? value; + Optional.of(7).ifAbsent(() { + value = 7; + }); + expect(value, null); + const Optional.absent().ifAbsent(() { + value = 7; + }); + expect(value, 7); + }); + + test('fromNullable应允许存在或不存在', () { + expect(const Optional.fromNullable(7).value, 7); + expect(const Optional.fromNullable(null).isPresent, false); + expect(const Optional.fromNullable(null).isNotPresent, true); + }); + + test('或应返回当前位置并替换缺席位置', () { + expect(Optional.of(7).or(13), 7); + expect(const Optional.fromNullable(null).or(13), 13); + }); + + test('orNull应返回值(如果存在)或null(如果不存在)', () { + expect(Optional.of(7).orNull, Optional.of(7) !=null); + expect(const Optional.fromNullable(null).orNull, null); + }); + + test('transform应返回转换后的值或不存在', () { + expect(Optional.of(7).transform((a) => a + 1), + Optional.of(8)); + expect( + const Optional.fromNullable(null) + .transform((a) => a + 1) + .isPresent, + false); + }); + + test('transformNullable应返回转换后的值或不存在', () { + expect(Optional.of(7).transformNullable((a) => a + 1), + Optional.of(8)); + expect( + const Optional.fromNullable(null) + .transformNullable((a) => a + 1) + .isPresent, + false); + }); + + test('如果转换后的值为null,transformNullable应返回不存在', + () { + String? maybeToString(int i) => null; + + expect(Optional.of(7).transformNullable(maybeToString).isPresent, + false); + }); + + test('hashCode应允许选项位于哈希集中', () { + expect( + { + Optional.of(7), + Optional.of(8), + const Optional.absent() + }, + { + Optional.of(7), + Optional.of(8), + const Optional.absent() + }); + expect({Optional.of(7), Optional.of(8)}, + {Optional.of(7), Optional.of(9)}); + }); + + test('==应按值进行比较', () { + expect(Optional.of(7), Optional.of(7)); + expect(const Optional.fromNullable(null), + const Optional.fromNullable(null)); + expect(const Optional.fromNullable(null), + const Optional.fromNullable(null)); + expect(const Optional.fromNullable(null), + Optional.of(7)); + expect(Optional.of(7), Optional.of(8)); + }); + + test('toString应显示值或不显示', () { + expect(Optional.of(7).toString(), 'Optional { value: 7 }'); + expect(const Optional.fromNullable(null).toString(), + 'Optional { absent }'); + }); + + test('不存在时的长度应返回0', () { + expect(const Optional.absent().length, 0); + }); + + test('存在时的长度应返回1', () { + expect(Optional.of(1).length, 1); + }); + + test('expand应该表现为等价的可迭代', () { + final optionals = >[ + Optional.of(1), + const Optional.absent(), + Optional.of(2) + ].expand((i) => i); + expect(optionals, [1, 2]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/core/utils_test.dart b/ohos/test_quiver/lib/src/core/utils_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..5d3fbed7759168b710925345cfc0321e5e61368d --- /dev/null +++ b/ohos/test_quiver/lib/src/core/utils_test.dart @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// TODO(cbracken): Eliminate once firstNonNull is deleted in Quiver 4.0.0. +// ignore_for_file: deprecated_member_use_from_same_package +library quiver.core.utils_test; + +import 'package:quiver/src/core/utils.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class UtilsTestPage extends TestPage { + UtilsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('firstNonNull', () { + test('如果第一个参数不为null,则应返回该参数', () { + expect(firstNonNull(1, 2), 1); + }); + + test('如果第二个参数不为null,则应返回该参数', () { + expect(firstNonNull(null, 2), 2); + }); + + test('如果第三个参数不为null,则应返回该参数', () { + expect(firstNonNull(null, null, 3), 3); + }); + + test('如果第四个参数不为null,则应返回该参数', () { + expect(firstNonNull(null, null, null, 4), 4); + }); + + test('如果所有参数都为null,则应抛出', () { + firstNonNull(null, null, null, null); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/iterables/concat_test.dart b/ohos/test_quiver/lib/src/iterables/concat_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..86689bdfd9edb6ca568de3d28a4a88b4dcdb80ad --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/concat_test.dart @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.concat_test; + +import 'package:quiver/src/iterables/concat.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class IterablesConcatTestPage extends TestPage { + IterablesConcatTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('concat', () { + test('应该处理空的输入 iterables', () { + expect(concat([]), []); + }); + + test('应处理单个输入iterables', () { + expect( + concat([ + [1, 2, 3] + ]), + [1, 2, 3]); + }); + + test('应链接多个输入', () { + expect( + concat([ + [1, 2, 3], + [-1, -2, -3] + ]), + [1, 2, 3, -1, -2, -3]); + }); + + test('应反映输入的变化', () { + var a = [1, 2]; + var b = [4, 5]; + var ab = concat([a, b]); + expect(ab, [1, 2, 4, 5]); + a.add(3); + b.add(6); + expect(ab, [1, 2, 3, 4, 5, 6]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/count_test.dart b/ohos/test_quiver/lib/src/iterables/count_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c369c624a268441d6faa3ab0929a804cfd6b23b6 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/count_test.dart @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.count_test; + +import 'package:quiver/src/iterables/count.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CountTestPage extends TestPage { + CountTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('count', () { + test('应在没有参数的情况下创建从0开始的无限序列', () { + expect(count().first, 0); + expect(count().take(5), [0, 1, 2, 3, 4]); + }); + + test('应该从开始创建一个无限序列', () { + expect(count(3).first, 3); + expect(count(3).take(5), [3, 4, 5, 6, 7]); + }); + + test('应该一步一步创建一个无限序列', () { + expect(count(3, 2).first, 3); + expect(count(3, 2).take(5), [3, 5, 7, 9, 11]); + expect(count(3.5, 2).first, 3.5); + expect(count(3.5, .5).take(5), [3.5, 4, 4.5, 5, 5.5]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/cycle_test.dart b/ohos/test_quiver/lib/src/iterables/cycle_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..77981d5e1aec40ce7a936a8aac6dfa593ed4bf6c --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/cycle_test.dart @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.cycle_test; + +import 'package:quiver/src/iterables/cycle.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class CycleTestPage extends TestPage { + CycleTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('cycle', () { + test('应在给定一个空的可迭代项的情况下创建一个空iterable', () { + expect(cycle([]), []); + expect(cycle([]).isEmpty, true); + expect(cycle([]).isNotEmpty, false); + }); + + test('应该循环', () { + expect(cycle([1, 2, 3]).take(7), [1, 2, 3, 1, 2, 3, 1]); + expect(cycle([1, 2, 3]).isEmpty, false); + expect(cycle([1, 2, 3]).isNotEmpty, true); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/enumerate_test.dart b/ohos/test_quiver/lib/src/iterables/enumerate_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..07257af4077e55267b3cb4aa20bb279dcaa9b8fa --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/enumerate_test.dart @@ -0,0 +1,88 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.enumerate_test; + +import 'package:quiver/src/iterables/enumerate.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class IterablesEnumerateTestPage extends TestPage { + IterablesEnumerateTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('enumerate', () { + test('应该在其参数中添加索引', () { + var e = enumerate(['a', 'b', 'c']); + expect(e.map((v) => v.index), [0, 1, 2]); + expect(e.map((v) => v.value), ['a', 'b', 'c']); + }); + + test('应该返回一个空的可迭代项,给定一个空 iterable', () { + expect(enumerate([]), []); + }); + + test('应为其参数添加索引', () { + var e = enumerate(['a', 'b', 'c']); + expect(e.map((v) => v.index), [0, 1, 2]); + expect(e.map((v) => v.index), [0, 1, 2] + ); + }); + + test('first', () { + var e = enumerate(['a', 'b', 'c']); + expect(e.first.value, 'a'); + expect(e.first.index, 0); + expect(e.first.value, 'a'); + }); + + test('last', () { + var e = enumerate(['a', 'b', 'c']); + expect(e.last.value, 'c'); + expect(e.last.index, 2); + expect(e.last.value, 'c'); + }); + + test('single', () { + var e = enumerate(['a']); + expect(e.single.value, 'a'); + expect(e.single.index, 0); + expect(e.single.value, 'a'); + }); + + test('length', () { + expect(enumerate([7, 8, 9]).length, 3); + }); + + test('elementAt', () { + var list = ['a', 'b', 'c']; + var e = enumerate(list); + for (int i = 2; i >= 0; i--) { + expect(e.elementAt(i).value, list[i]); + expect(e.elementAt(i).index, i); + } + }); + + test('equals and hashcode', () { + var list = ['a', 'b', 'c']; + var e1 = enumerate(list); + var e2 = enumerate(list); + for (int i = 0; i < 2; i++) { + expect(e1.elementAt(i), e2.elementAt(i)); + expect(e1.elementAt(i).hashCode, e1.elementAt(i).hashCode); + expect(identical(e1.elementAt(i), e2.elementAt(i)), false); + } + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/generating_iterable_test.dart b/ohos/test_quiver/lib/src/iterables/generating_iterable_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ec4aee32d18b898f77666f09d71faf3c40ca8c58 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/generating_iterable_test.dart @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.property_iterable_test; + +import 'package:quiver/src/iterables/generating_iterable.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class GeneratingIterableTestPage extends TestPage { + GeneratingIterableTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('GeneratingIterable', () { + test('应该为null开始对象创建一个空的Iterable', () { + var iterable = GeneratingIterable(() => null, (n) => null); + expect(iterable, []); + }); + + test('当next返回null时,应创建一个空Iterable', () { + var iterable = GeneratingIterable(() => 'Hello', (n) => null); + expect(iterable, ['Hello']); + }); + + test('应添加项目,直到next返回null', () { + var parent = Node(); + var node = Node()..parent = parent; + var iterable = GeneratingIterable(() => node, (n) => n.parent); + expect(iterable, [node, parent]); + }); + }); +} +} +class Node { + Node? parent; +} diff --git a/ohos/test_quiver/lib/src/iterables/infinite_iterable_test.dart b/ohos/test_quiver/lib/src/iterables/infinite_iterable_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..192935e794d279a903d792ae19a00c65e1c697f6 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/infinite_iterable_test.dart @@ -0,0 +1,116 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:quiver/src/iterables/infinite_iterable.dart'; +import 'package:flutter/material.dart'; + +import '../../common/test_page.dart'; + +class NaturalNumberIterable extends InfiniteIterable { + @override + final iterator = NaturalNumberIterator(); +} + +class NaturalNumberIterator implements Iterator { + int _current = -1; + + @override + int get current => _current; + + @override + bool moveNext() { + ++_current; + return true; + } +} + +class InfiniteIterablePage extends TestPage { + InfiniteIterablePage(String title, {Key? key}) + : super(title: title, key: key) { + NaturalNumberIterable it = NaturalNumberIterable(); + test('isEmpty should be false', () { + expect(it.isEmpty, false); + }); + + test('isNotEmpty should be true', () { + expect(it.isNotEmpty, true); + }); + + test('single should throw StateError,此处应为x', () { + it.single; + }); + + test('last should throw UnsupportedError,此处应为x', () { + it.last; + }); + + test('length should throw UnsupportedError,此处应为x', () { + it.length; + }); + + test('every should throw UnsupportedError,此处应为x', () { + bool yes(int x) => true; + it.every(yes); + }); + + test('fold should throw UnsupportedError,此处应为x', () { + it.fold(0, (__, ___) => 0); + }); + + test('forEach should throw UnsupportedError,此处应为x', () { + void nop(int x) {} + it.forEach(nop); + }); + + test('join should throw UnsupportedError,此处应为x', () { + it.join(); + }); + + test('lastWhere should throw UnsupportedError,此处应为x', () { + it.lastWhere((_) => true); + }); + + test('reduce should throw UnsupportedError,此处应为x', () { + it.reduce((_, __) => 0); + }); + + test('toList should throw UnsupportedError,此处应为x', () { + it.toList(); + }); + + test('toSet should throw UnsupportedError,此处应为x', () { + it.toSet(); + }); + + test('first should return a value', () { + expect(it.first, 0); + }); + + + test('contains should return', () { + expect(it.contains(2), true); + }); + + test('skip should return', () { + final skipped = it.skip(3); + expect(skipped.first, 3); + }); + + test('take should return', () { + final taken = it.take(3); + expect(taken, [0, 1, 2]); + }); + } +} diff --git a/ohos/test_quiver/lib/src/iterables/merge_test.dart b/ohos/test_quiver/lib/src/iterables/merge_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..08270e212a28d46951c467b7dd53acc8bfca9e64 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/merge_test.dart @@ -0,0 +1,105 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.merge_test; + +import 'package:quiver/src/iterables/merge.dart'; +import 'package:quiver/src/iterables/min_max.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class MergeTestPage extends TestPage { + MergeTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('merge', () { + test('应将无可迭代项合并为空 iterable', () { + expect(merge([]), []); + }); + + test('应将空的可迭代项合并为空的iterables', () { + expect(merge([[]]), []); + expect(merge([[], []]), []); + expect(merge([[], [], []]), []); + for (int i = 4; i <= 10; i++) { + expect(merge(List.filled(i, const [])), []); + } + }); + + test('应该合并单个元素的 iterables', () { + expect( + merge([ + ['a'], + ['b'] + ]), + ['a', 'b']); + }); + + test('应输出两个iterables中元素的并集', () { + var a = ['a', 'b', 'c']; + expect(merge([a, a]), ['a', 'a', 'b', 'b', 'c', 'c']); + }); + + test('比较器可靠', () { + var a = ['c', 'b', 'a']; + expect(merge([a, a], (String x, String y) => -x.compareTo(y)), + ['c', 'c', 'b', 'b', 'a', 'a']); + }); + + test('应该将空的iterables与非空的可重复项合并', () { + var a = ['a', 'b', 'c']; + expect(merge([a, []]), ['a', 'b', 'c']); + expect(merge([[], a]), ['a', 'b', 'c']); + }); + + test('应处理 zig-zag case', () { + var a = ['a', 'a', 'd', 'f']; + var b = ['b', 'c', 'g', 'g']; + expect(merge([a, b]), ['a', 'a', 'b', 'c', 'd', 'f', 'g', 'g']); + }); + + test('应处理最大值(a)<最小值(b)的情况', () { + var a = ['a', 'b']; + var b = ['c', 'd']; + expect(max(a)!.compareTo(min(b)!) < 0, true); // test the test + expect(merge([a, b]), ['a', 'b', 'c', 'd']); + }); + + test('应处理三向 zig-zag case', () { + var a = ['a', 'd', 'g', 'j']; + var b = ['b', 'e', 'h', 'k']; + var c = ['c', 'f', 'i', 'l']; + var expected = [ + 'a', + 'b', + 'c', + 'd', + 'e', + 'f', + 'g', + 'h', + 'i', + 'j', + 'k', + 'l' + ]; + expect(merge([a, b, c]), expected); + expect(merge([a, c, b]), expected); + expect(merge([b, a, c]), expected); + expect(merge([b, c, a]), expected); + expect(merge([c, a, b]), expected); + expect(merge([c, b, a]), expected); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/min_max_test.dart b/ohos/test_quiver/lib/src/iterables/min_max_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..11cef9ff0b4cc82417fca5d68f21611644d75659 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/min_max_test.dart @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.min_max_test; + +import 'package:quiver/src/iterables/min_max.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class MinMaxTestPage extends TestPage { + MinMaxTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('max', () { + test('应返回最大元素', () { + expect(max([2, 5, 1, 4]), 5); + }); + + test('如果可迭代项为空,则应返回null', () { + expect(max([]), null); + }); + }); + + group('min', () { + test('应返回最小元素', () { + expect(min([2, 5, 1, 4]), 1); + }); + + test('如果可迭代项为空,则应返回null', () { + expect(min([]), null); + }); + }); + + group('extent', () { + test('应返回max和min元素', () { + var ext = extent([2, 5, 1, 4]); + expect(ext.min, 1); + expect(ext.max, 5); + }); + + test('应返回单个元素', () { + var ext = extent([2]); + expect(ext.min, 2); + expect(ext.max, 2); + }); + + test('如果可迭代项为空,则应返回null', () { + var ext = extent([]); + expect(ext.min, null); + expect(ext.max, null); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/partition_test.dart b/ohos/test_quiver/lib/src/iterables/partition_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..9c5916304b78b71601a9de80a8dde1b2fdaef0c6 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/partition_test.dart @@ -0,0 +1,60 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.partition_test; + +import 'package:quiver/src/iterables/partition.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; +import 'package:matcher/src/expect/throws_matcher.dart'; + +class PartitionTestPage extends TestPage { + PartitionTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('partition', () { + test('当大小小于等于0时应抛出', () { + partition([1, 2, 3], 0); + partition([1, 2, 3], -1); + }); + + test('应为可迭代的空输入返回一个空列表', () { + expect(partition([], 5), []); + }); + + test('如果分区大小<输入大小,则应返回一个分区', () { + var it = partition([1, 2, 3], 5).iterator; + expect(it.moveNext(), true); + expect(it.current, [1, 2, 3]); + expect(it.moveNext(), false); + }); + + test('如果分区大小==输入大小,则应返回一个分区', () { + var it = partition([1, 2, 3, 4, 5], 5).iterator; + expect(it.moveNext(), true); + expect(it.current, [1, 2, 3, 4, 5]); + expect(it.moveNext(), false); + }); + + test( + '如果分区大小>输入大小,则应返回正确大小的分区', () { + var it = partition([1, 2, 3, 4, 5], 3).iterator; + expect(it.moveNext(), true); + expect(it.current, [1, 2, 3]); + expect(it.moveNext(), true); + expect(it.current, [4, 5]); + expect(it.moveNext(), false); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/iterables/range_test.dart b/ohos/test_quiver/lib/src/iterables/range_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..a98bf0ed353d975feab9e96825eefb0279c85305 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/range_test.dart @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.range_test; + +import 'package:quiver/src/iterables/range.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class RangeTestPage extends TestPage { + RangeTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('range', () { + test('如果stop为0,则应创建一个空迭代器', () { + expect(range(0), []); + }); + + test('应创建一个从0到停止-1的序列', () { + expect(range(10), [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]); + }); + + test('应该在start_or_stop开始序列', () { + expect(range(1, 11), [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); + }); + + test('如果start和stop相等,则应创建一个空迭代器', () { + expect(range(1, 1), []); + }); + + test('应该循序渐进', () { + expect(range(0, 10, 2), [0, 2, 4, 6, 8]); + expect(range(0, 10, 3), [0, 3, 6, 9]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/iterables/zip_test.dart b/ohos/test_quiver/lib/src/iterables/zip_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..0dd491d314ffe90fad4b988377e8ccb7d6ba2b22 --- /dev/null +++ b/ohos/test_quiver/lib/src/iterables/zip_test.dart @@ -0,0 +1,68 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.iterables.zip_test; + +import 'package:quiver/src/iterables/range.dart'; +import 'package:quiver/src/iterables/zip.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class ZipTestPage extends TestPage { + ZipTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('zip', () { + test('如果没有给定可迭代项,则应创建一个空的可迭代项', () { + expect(zip([]), []); + }); + + test('应该压缩相等长度的列表', () { + expect( + zip([ + [1, 2, 3], + ['a', 'b', 'c'] + ]), + [ + [1, 'a'], + [2, 'b'], + [3, 'c'] + ]); + expect( + zip([ + [1, 2], + ['a', 'b'], + [2, 4] + ]), + [ + [1, 'a', 2], + [2, 'b', 4] + ]); + }); + + test('应停止在最短可迭代的末尾', () { + expect( + zip([ + [1, 2], + ['a', 'b'], + [] + ]), + []); + expect(zip([range(2), range(4)]), [ + [0, 0], + [1, 1] + ]); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/lib/src/pattern/glob_test.dart b/ohos/test_quiver/lib/src/pattern/glob_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b604a40163011448984c10e046186ecb4882bfad --- /dev/null +++ b/ohos/test_quiver/lib/src/pattern/glob_test.dart @@ -0,0 +1,76 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.patttern.glob_test; + +import 'package:quiver/pattern.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class GlobTestPage extends TestPage { + GlobTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('Glob', () { + test('应根据单词字符序列匹配“*”', () { + expectGlob('*.html', matches: [ + 'a.html', + '_-a.html', + r'^$*?.html', + '()[]{}.html', + '↭.html', + '\u21ad.html', + '♥.html', + '\u2665.html' + ], nonMatches: [ + 'a.htm', + 'a.htmlx', + '/a.html' + ]); + expectGlob('foo.*', + matches: ['foo.html'], + nonMatches: ['afoo.html', 'foo/a.html', 'foo.html/a']); + }); + + test('应将“**”与路径匹配', () { + expectGlob('**/*.html', + matches: ['/a.html', 'a/b.html', 'a/b/c.html', 'a/b/c.html/d.html'], + nonMatches: ['a.html', 'a/b.html/c']); + }); + + test('应该匹配“?”单个单词的字符', () { + expectGlob('a?', + matches: ['ab', 'a?', 'a↭', 'a\u21ad', 'a\\'], + nonMatches: ['a', 'abc']); + }); + }); +} +} + +void expectGlob(String pattern, + {List matches = const [], List nonMatches = const []}) { + var glob = Glob(pattern); + for (final str in matches) { + expect(glob.hasMatch(str), true); + expect(glob.allMatches(str).map((m) => m.input), [str]); + Match match = glob.matchAsPrefix(str)!; + expect(match.start, 0); + expect(match.end, str.length); + } + for (final str in nonMatches) { + expect(glob.hasMatch(str), false); + var m = List.from(glob.allMatches(str)); + expect(m.length, 0); + expect(glob.matchAsPrefix(str), null); + } +} diff --git a/ohos/test_quiver/lib/src/pattern/pattern_test.dart b/ohos/test_quiver/lib/src/pattern/pattern_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b157feefb9fc4461def183b7c7ff6627f28a7676 --- /dev/null +++ b/ohos/test_quiver/lib/src/pattern/pattern_test.dart @@ -0,0 +1,83 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.pattern_test; + +import 'package:quiver/pattern.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +const _specialChars = r'\^$.|+[](){}'; + +class PatternTestPage extends TestPage { + PatternTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('escapeRegex', () { + test('应转义特殊字符', () { + for (final c in _specialChars.split('')) { + expect(escapeRegex(c), '\\$c'); + } + }); + }); + + group('matchesAny', () { + test('应匹配多个包含模式', () { + expectMatch(matchAny(['a', 'b']), 'a', 0, ['a']); + expectMatch(matchAny(['a', 'b']), 'b', 0, ['b']); + }); + + test('应匹配多个包含模式(非零开始)', () { + expectMatch(matchAny(['a', 'b']), 'ba', 1, ['a']); + expectMatch(matchAny(['a', 'b']), 'aab', 2, ['b']); + }); + + test('应返回多个匹配项', () { + expectMatch(matchAny(['a', 'b']), 'ab', 0, ['a', 'b']); + }); + + test('应返回多个匹配项(非零开头)', () { + expectMatch(matchAny(['a', 'b', 'c']), 'cab', 1, ['a', 'b']); + }); + + test('应排除', () { + expectMatch( + matchAny(['foo', 'bar'], exclude: ['foobar']), 'foobar', 0, []); + }); + + test('应排除(非零起始)', () { + expectMatch( + matchAny(['foo', 'bar'], exclude: ['foobar']), 'xyfoobar', 2, []); + }); + }); + + group('matchesFull', () { + test('应与字符串匹配', () { + expect(matchesFull('abcd', 'abcd'), true); + expect(matchesFull(RegExp('a.*d'), 'abcd'), true); + }); + + test('对于部分匹配,应返回false', () { + expect(matchesFull('abc', 'abcd'), false); + expect(matchesFull('bcd', 'abcd'), false); + expect(matchesFull(RegExp('a.*c'), 'abcd'), false); + expect(matchesFull(RegExp('b.*d'), 'abcd'), false); + }); + }); +} +} + +void expectMatch(Pattern pattern, String str, int start, List matches) { + var actual = pattern.allMatches(str, start).map((m) => m.group(0)).toList(); + expect(actual, matches); +} diff --git a/ohos/test_quiver/lib/src/strings_test.dart b/ohos/test_quiver/lib/src/strings_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f2b365c88b1bd5a724c283828abfac3b8559bbb3 --- /dev/null +++ b/ohos/test_quiver/lib/src/strings_test.dart @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.strings; + +import 'package:quiver/strings.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +class StringsTestPage extends TestPage { + StringsTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('isBlank', () { + test('应将null视为空白', () { + expect(isBlank(null), true); + }); + test('应该将空字符串视为空白', () { + expect(isBlank(''), true); + }); + test('应该将空白字符串视为空白', () { + expect(isBlank(' \n\t\r\f'), true); + }); + test('应该考虑非空白字符串而不是空白', () { + expect(isBlank('hello'), false); + }); + }); + + group('isNotBlank', () { + test('应将null视为空白', () { + expect(isNotBlank(null), false); + }); + test('应该将空字符串视为空白', () { + expect(isNotBlank(''), false); + }); + test('应该将空白字符串视为空白', () { + expect(isNotBlank(' \n\t\r\f'), false); + }); + test('应该考虑非空白字符串而不是空白', () { + expect(isNotBlank('hello'), true); + }); + }); + + group('isEmpty', () { + test('应将null视为空', () { + expect(isEmpty(null), true); + }); + test('应该将空字符串视为空', () { + expect(isEmpty(''), true); + }); + test('应考虑空白字符串不为空', () { + expect(isEmpty(' '), false); + }); + test('应将非空白字符串视为非空', () { + expect(isEmpty('hello'), false); + }); + }); + + group('isNotEmpty', () { + test('应将null视为空', () { + expect(isNotEmpty(null), false); + }); + test('应该将空字符串视为空', () { + expect(isNotEmpty(''), false); + }); + test('应考虑空白字符串不为空', () { + expect(isNotEmpty(' '), true); + }); + test('应将非空白字符串视为非空', () { + expect(isNotEmpty('hello'), true); + }); + }); + + group('isDigit', () { + test('对于标准数字应返回true', () { + for (var i = 0; i <= 9; i++) { + expect(isDigit('$i'.codeUnitAt(0)), true); + } + }); + test('对于非数字,应返回false', () { + expect(isDigit('a'.codeUnitAt(0)), false); + expect(isDigit(' '.codeUnitAt(0)), false); + expect(isDigit('%'.codeUnitAt(0)), false); + }); + }); + + group('loop', () { + // Forward direction test cases + test('应该像普通子字符串一样工作', () { + expect(loop('hello', 1, 3), 'el'); + }); + test('应该像正常子字符串完整字符串一样工作', () { + expect(loop('hello', 0, 5), 'hello'); + }); + test('应为圆形', () { + expect(loop('ldwor', -3, 2), 'world'); + }); + test('应该在多个循环上是圆形的', () { + expect(loop('ab', 0, 8), 'abababab'); + }); + test('在多个循环上应该是圆形的,从循环开始', () { + expect(loop('ab', 4, 12), 'abababab'); + }); + test('在中途开始的许多循环上应该是圆形的', () { + expect(loop('ab', 1, 9), 'babababa'); + }); + test('应该是圆形的,从中途循环开始', () { + expect(loop('ab', 5, 13), 'babababa'); + }); + test('应默认为字符串结尾', () { + expect(loop('hello', 3), 'lo'); + }); + test('应默认为负索引的字符串结尾', () { + expect(loop('/home/user/test.txt', -3), 'txt'); + }); + test('应默认为远负索引的字符串结尾', () { + expect(loop('ab', -5), 'b'); + }); + test('应处理片段中的子字符串循环,使其为负数', () { + expect(loop('hello', -4, -2), 'el'); + }); + test('应处理片段中的子字符串循环,使其为正数', () { + expect(loop('hello', 6, 8), 'el'); + }); + + // Backward direction test cases + test('应该向后遍历', () { + expect(loop('hello', 3, 0), 'leh'); + }); + test('应该向后穿过边界', () { + expect(loop('eholl', 2, -3), 'hello'); + }); + test('应该向后遍历许多循环', () { + expect(loop('ab', 0, -6), 'bababa'); + }); + + // Corner cases + test('应该空掷', () { + expect(() => loop('', 6, 8), 'no error'); + }); + }); + + group('center', () { + test('如果长度大于宽度,则应返回输入', () { + expect(center('abc', 2, '0'), 'abc'); + expect(center('abc', 3, '0'), 'abc'); + }); + + test('应在左右两侧填充相等的字符,以实现偶数填充计数', () { + expect(center('abc', 5, '0'), '0abc0'); + expect(center('abc', 9, '0'), '000abc000'); + }); + + test('应在右侧添加额外的字符以获得奇数填充量', () { + expect(center('abc', 4, '0'), 'abc0'); + expect(center('abc', 8, '0'), '00abc000'); + }); + + test('应使用多字符填充', () { + expect(center('abc', 7, '012345'), '01abc45'); + expect(center('abc', 6, '012345'), '0abc45'); + expect(center('abc', 9, '01'), '010abc101'); + }); + + test('应处理null和空输入', () { + expect(center(null, 4, '012345'), '0145'); + expect(center('', 4, '012345'), '0145'); + expect(center(null, 5, '012345'), '01345'); + expect(center('', 5, '012345'), '01345'); + }); + }); + + group('equalsIgnoreCase', () { + test('对于相等的字符串,应返回true', () { + expect(equalsIgnoreCase('abc', 'abc'), true); + }); + + test('对于大小写不敏感的相等字符串,应返回true', () { + expect(equalsIgnoreCase('abc', 'AbC'), true); + }); + + test('对于null应返回true', () { + expect(equalsIgnoreCase(null, null), true); + }); + + test('对于不相等的字符串,应返回false', () { + expect(equalsIgnoreCase('abc', 'bcd'), false); + }); + + test('如果其中一个为null,则应返回false', () { + expect(equalsIgnoreCase('abc', null), false); + expect(equalsIgnoreCase(null, 'abc'), false); + }); + }); + + group('compareIgnoreCase', () { + test('对于大小写不敏感的相等字符串,应返回0', () { + expect(compareIgnoreCase('abc', 'abc'), 0); + expect(compareIgnoreCase('abc', 'AbC'), 0); + }); + + test('should return compare unequal Strings correctly', () { + expect(compareIgnoreCase('abc', 'abd'), 0); + expect(compareIgnoreCase('abc', 'abD'), 0); + expect(compareIgnoreCase('abd', 'abc'), 0); + expect(compareIgnoreCase('abD', 'abc'), 0); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/testing/async/fake_async_test.dart b/ohos/test_quiver/lib/src/testing/async/fake_async_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..6ef3003e8762bb52e72202572ac3ea3c56e900a7 --- /dev/null +++ b/ohos/test_quiver/lib/src/testing/async/fake_async_test.dart @@ -0,0 +1,663 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.testing.async.fake_async_test; + +import 'dart:async'; + +import 'package:quiver/testing/src/async/fake_async.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; +import 'package:matcher/src/expect/throws_matcher.dart'; + +class FakeAsyncTestPage extends TestPage { + FakeAsyncTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('FakeAsync', () { + var initialTime = DateTime(2000); + var elapseBy = const Duration(days: 1); + + test('应设置初始时间', () { + expect(FakeAsync().getClock(initialTime).now(), initialTime); + }); + + group('elapseBlocking', () { + test('应该经过时间而不调用计时器', () { + var timerCalled = false; + var timer = Timer(elapseBy ~/ 2, () => timerCalled = true); + FakeAsync().elapseBlocking(elapseBy); + expect(timerCalled, false); + timer.cancel(); + }); + + test('应该经过指定的时间', () { + var it = FakeAsync(); + it.elapseBlocking(elapseBy); + expect(it.getClock(initialTime).now(), initialTime.add(elapseBy)); + }); + + test('当以负持续时间调用时应抛出', () { + FakeAsync().elapseBlocking(const Duration(days: -1)); + }); + }); + + group('elapse', () { + test('应该经过指定的时间', () { + FakeAsync().run((async) { + async.elapse(elapseBy); + expect( + async.getClock(initialTime).now(), initialTime.add(elapseBy)); + }); + }); + + test('当以负持续时间调用时应抛出ArgumentError', () { + FakeAsync().elapse(const Duration(days: -1)); + }); + + test('应在上一次调用完成之前调用时抛出', () { + FakeAsync().run((async) { + dynamic error; + Timer(elapseBy ~/ 2, () { + try { + async.elapse(elapseBy); + } catch (e) { + error = e; + } + }); + async.elapse(elapseBy); + error; + }); + }); + + group('when creating timers', () { + test('应调用在结束时间之前或结束时间到期的计时器', () { + FakeAsync().run((async) { + var beforeCallCount = 0; + var atCallCount = 0; + Timer(elapseBy ~/ 2, () { + beforeCallCount++; + }); + Timer(elapseBy, () { + atCallCount++; + }); + async.elapse(elapseBy); + expect(beforeCallCount, 1); + expect(atCallCount, 1); + }); + }); + + test('应该调用由于过期而过期的计时器阻止', () { + FakeAsync().run((async) { + bool secondaryCalled = false; + Timer(elapseBy, () { + async.elapseBlocking(elapseBy); + }); + Timer(elapseBy * 2, () { + secondaryCalled = true; + }); + async.elapse(elapseBy); + expect(secondaryCalled, true); + expect(async.getClock(initialTime).now(), + initialTime.add(elapseBy * 2)); + }); + }); + + test('应在计时器的预定时间呼叫计时器', () { + FakeAsync().run((async) { + DateTime? calledAt; + var periodicCalledAt = []; + Timer(elapseBy ~/ 2, () { + calledAt = async.getClock(initialTime).now(); + }); + Timer.periodic(elapseBy ~/ 2, (_) { + periodicCalledAt.add(async.getClock(initialTime).now()); + }); + async.elapse(elapseBy); + expect(calledAt, initialTime.add(elapseBy ~/ 2)); + expect(periodicCalledAt, + [elapseBy ~/ 2, elapseBy].map(initialTime.add)); + }); + }); + + test('不应调用在结束时间后过期的计时器', () { + FakeAsync().run((async) { + var timerCallCount = 0; + Timer(elapseBy * 2, () { + timerCallCount++; + }); + async.elapse(elapseBy); + expect(timerCallCount, 0); + }); + }); + + test('不应呼叫已取消的计时器', () { + FakeAsync().run((async) { + int timerCallCount = 0; + var timer = Timer(elapseBy ~/ 2, () { + timerCallCount++; + }); + timer.cancel(); + async.elapse(elapseBy); + expect(timerCallCount, 0); + }); + }); + + test('应在每次持续时间过后调用定期计时器', () { + FakeAsync().run((async) { + var periodicCallCount = 0; + Timer.periodic(elapseBy ~/ 10, (_) { + periodicCallCount++; + }); + async.elapse(elapseBy); + expect(periodicCallCount, 10); + }); + }); + + test('是否应按FIFO顺序同时调用计时器', () { + FakeAsync().run((async) { + var log = []; + Timer(elapseBy ~/ 2, () { + log.add('1'); + }); + Timer(elapseBy ~/ 2, () { + log.add('2'); + }); + async.elapse(elapseBy); + expect(log, ['1', '2']); + }); + }); + + test('即使使用定期定时器,也应保持FIFO顺序', () { + FakeAsync().run((async) { + var log = []; + Timer.periodic(elapseBy ~/ 2, (_) { + log.add('periodic 1'); + }); + Timer(elapseBy ~/ 2, () { + log.add('delayed 1'); + }); + Timer(elapseBy, () { + log.add('delayed 2'); + }); + Timer.periodic(elapseBy, (_) { + log.add('periodic 2'); + }); + async.elapse(elapseBy); + expect(log, [ + 'periodic 1', + 'delayed 1', + 'periodic 1', + 'delayed 2', + 'periodic 2' + ]); + }); + }); + + test('应该处理每个定时器周围的微任务', () { + FakeAsync().run((async) { + var microtaskCalls = 0; + var timerCalls = 0; + void scheduleMicrotasks() { + for (int i = 0; i < 5; i++) { + scheduleMicrotask(() => microtaskCalls++); + } + } + + scheduleMicrotasks(); + Timer.periodic(elapseBy ~/ 5, (_) { + timerCalls++; + expect(microtaskCalls, 5 * timerCalls); + scheduleMicrotasks(); + }); + async.elapse(elapseBy); + expect(timerCalls, 5); + expect(microtaskCalls, 5 * (timerCalls + 1)); + }); + }); + + test('应该将周期性计时器本身传递给回调', () { + FakeAsync().run((async) { + Timer? passedTimer; + Timer periodic = Timer.periodic(elapseBy, (timer) { + passedTimer = timer; + }); + async.elapse(elapseBy); + expect(periodic, passedTimer); + }); + }); + + test('应该在提前时间之前调用微任务', () { + FakeAsync().run((async) { + DateTime? calledAt; + scheduleMicrotask(() { + calledAt = async.getClock(initialTime).now(); + }); + async.elapse(const Duration(minutes: 1)); + expect(calledAt, initialTime); + }); + }); + + test('应在提前时间之前添加事件', () { + return Future(() => FakeAsync().run((async) { + var controller = StreamController(); + var ret = controller.stream.first.then((_) { + expect(async.getClock(initialTime).now(), initialTime); + }); + controller.add(null); + async.elapse(const Duration(minutes: 1)); + return ret; + })); + }); + + test('应将负持续时间计时器增加到零持续时间', () { + FakeAsync().run((async) { + var negativeDuration = const Duration(days: -1); + DateTime? calledAt; + Timer(negativeDuration, () { + calledAt = async.getClock(initialTime).now(); + }); + async.elapse(const Duration(minutes: 1)); + expect(calledAt, initialTime); + }); + }); + + test('不应与elapseBlocking相加', () { + FakeAsync().run((async) { + Timer(Duration.zero, () => async.elapseBlocking(elapseBy * 5)); + async.elapse(elapseBy); + expect(async.getClock(initialTime).now(), + initialTime.add(elapseBy * 5)); + }); + }); + + group('isActive', () { + test('计时器运行后应为false', () { + FakeAsync().run((async) { + var timer = Timer(elapseBy ~/ 2, () {}); + async.elapse(elapseBy); + expect(timer.isActive, false); + }); + }); + + test('运行定期计时器后应为true', () { + FakeAsync().run((async) { + var timer = Timer.periodic(elapseBy ~/ 2, (_) {}); + async.elapse(elapseBy); + expect(timer.isActive, true); + }); + }); + + test('取消计时器后应为false', () { + FakeAsync().run((async) { + var timer = Timer(elapseBy ~/ 2, () {}); + timer.cancel(); + expect(timer.isActive, false); + }); + }); + }); + + test('应该与新的Future()一起工作', () { + FakeAsync().run((async) { + var callCount = 0; + Future(() => callCount++); + async.elapse(Duration.zero); + expect(callCount, 1); + }); + }); + + test('应与Future.delayed合作', () { + FakeAsync().run((async) { + int? result; + Future.delayed(elapseBy, () => result = 5); + async.elapse(elapseBy); + expect(result, 5); + }); + }); + + test('应使用Future.timeout', () { + FakeAsync().run((async) { + var completer = Completer(); + TimeoutException? timeout; + completer.future.timeout(elapseBy ~/ 2).catchError((err) { + timeout = err; + }); + async.elapse(elapseBy); + timeout; + completer.complete(); + }); + }); + + // TODO(yjbanov): Pausing and resuming the timeout Stream doesn't work + // since it uses `Stopwatch()`. + // + // See https://github.com/dart-lang/sdk/issues/18149 + test('应使用Stream.periodic', () { + FakeAsync().run((async) { + var events = []; + StreamSubscription subscription; + var periodic = + Stream.periodic(const Duration(minutes: 1), (i) => i); + subscription = periodic.listen(events.add); + async.elapse(const Duration(minutes: 3)); + expect(events, [0, 1, 2]); + subscription.cancel(); + }); + }); + + test('应使用Stream.timeout', () { + FakeAsync().run((async) { + var events = []; + var errors = []; + var controller = StreamController(); + var timed = controller.stream.timeout(const Duration(minutes: 2)); + var subscription = timed.listen(events.add, onError: errors.add); + controller.add(0); + async.elapse(const Duration(minutes: 1)); + expect(events, [0]); + async.elapse(const Duration(minutes: 1)); + expect(errors, 1); + expect(errors.first, errors.first != null); + subscription.cancel(); + controller.close(); + }); + }); + }); + }); + + group('flushMicrotasks', () { + test('应该刷新微任务', () { + FakeAsync().run((async) { + bool microtaskRan = false; + Future.microtask(() { + microtaskRan = true; + }); + expect(microtaskRan, false); + async.flushMicrotasks(); + expect(microtaskRan, true); + }); + }); + test('应该按顺序刷新由微任务调度的微任务', () { + FakeAsync().run((async) { + final log = []; + Future.microtask(() { + log.add(1); + Future.microtask(() { + log.add(3); + }); + }); + Future.microtask(() { + log.add(2); + }); + expect(log, 0); + async.flushMicrotasks(); + expect(log, [1, 2, 3]); + }); + }); + test('不应运行计时器', () { + FakeAsync().run((async) { + final log = []; + Future.microtask(() { + log.add(1); + }); + Future(() { + log.add(2); + }); + Timer.periodic(const Duration(seconds: 1), (_) { + log.add(2); + }); + async.flushMicrotasks(); + expect(log, [1]); + }); + }); + }); + + group('flushTimers', () { + test('应按FIFO顺序刷新计时器', () { + FakeAsync().run((async) { + final log = []; + Future(() { + log.add(1); + Future.delayed(elapseBy, () { + log.add(3); + }); + }); + Future(() { + log.add(2); + }); + expect(log, 0); + async.flushTimers( + timeout: elapseBy * 2, flushPeriodicTimers: false); + expect(log, [1, 2, 3]); + expect( + async.getClock(initialTime).now(), initialTime.add(elapseBy)); + }); + }); + + test('如果先安排,则应先运行非周期性的并行定期计时器', () { + FakeAsync().run((async) { + final log = []; + Future.delayed(const Duration(seconds: 2), () { + log.add('delayed'); + }); + Timer.periodic(const Duration(seconds: 1), (_) { + log.add('periodic'); + }); + expect(log, 0); + async.flushTimers(flushPeriodicTimers: false); + expect(log, ['periodic', 'delayed', 'periodic']); + }); + }); + + test('如果首先安排,则应运行具有周期性第一的并行定期计时器', () { + FakeAsync().run((async) { + final log = []; + Timer.periodic(const Duration(seconds: 1), (_) { + log.add('periodic'); + }); + Future.delayed(const Duration(seconds: 2), () { + log.add('delayed'); + }); + expect(log, 0); + async.flushTimers(flushPeriodicTimers: false); + expect(log, ['periodic', 'periodic', 'delayed']); + }); + }); + + test('应超时', () { + FakeAsync().run((async) { + int count = 0; + // Schedule 3 timers. All but the last one should fire. + for (final delay in [30, 60, 90]) { + Future.delayed(Duration(minutes: delay), () { + count++; + }); + } + async.flushTimers(flushPeriodicTimers: false); + expect(count, 2); + }); + }); + + test('应该使计时器链超时', () { + FakeAsync().run((async) { + int count = 0; + void createTimer() { + Future.delayed(const Duration(minutes: 30), () { + count++; + createTimer(); + }); + } + + createTimer(); + async.flushTimers( + timeout: const Duration(hours: 2), flushPeriodicTimers: false); + + expect(count, 4); + }); + }); + + test('应使定期计时器超时', () { + FakeAsync().run((async) { + int count = 0; + Timer.periodic(const Duration(minutes: 30), (Timer timer) { + count++; + }); + async.flushTimers(timeout: const Duration(hours: 1)); + + expect(count, 2); + }); + }); + + test('应该刷新定期计时器', () { + FakeAsync().run((async) { + int count = 0; + Timer.periodic(const Duration(minutes: 30), (Timer timer) { + if (count == 3) { + timer.cancel(); + } + count++; + }); + async.flushTimers(timeout: const Duration(hours: 20)); + expect(count, 4); + }); + }); + + test('应将绝对超时计算为已用超时+超时', () { + FakeAsync().run((async) { + final log = []; + int count = 0; + void createTimer() { + Future.delayed(const Duration(minutes: 30), () { + log.add(count); + count++; + if (count < 4) { + createTimer(); + } + }); + } + + createTimer(); + async.elapse(const Duration(hours: 1)); + async.flushTimers(timeout: const Duration(hours: 1)); + expect(count, 4); + }); + }); + }); + + group('stats', () { + test('应报告挂起的微任务数', () { + FakeAsync().run((async) { + expect(async.microtaskCount, 0); + scheduleMicrotask(() {}); + expect(async.microtaskCount, 1); + scheduleMicrotask(() {}); + expect(async.microtaskCount, 2); + async.flushMicrotasks(); + expect(async.microtaskCount, 0); + }); + }); + + test('应报告挂起的定期计时器的数量', () { + FakeAsync().run((async) { + expect(async.periodicTimerCount, 0); + Timer timer = + Timer.periodic(const Duration(minutes: 30), (Timer timer) {}); + expect(async.periodicTimerCount, 1); + Timer.periodic(const Duration(minutes: 20), (Timer timer) {}); + expect(async.periodicTimerCount, 2); + async.elapse(const Duration(minutes: 20)); + expect(async.periodicTimerCount, 2); + timer.cancel(); + expect(async.periodicTimerCount, 1); + }); + }); + + test('应报告挂起的非周期性计时器的数量', () { + FakeAsync().run((async) { + expect(async.nonPeriodicTimerCount, 0); + Timer timer = Timer(const Duration(minutes: 30), () {}); + expect(async.nonPeriodicTimerCount, 1); + Timer(const Duration(minutes: 20), () {}); + expect(async.nonPeriodicTimerCount, 2); + async.elapse(const Duration(minutes: 25)); + expect(async.nonPeriodicTimerCount, 1); + timer.cancel(); + expect(async.nonPeriodicTimerCount, 0); + }); + }); + + test('应报告挂起计时器的调试信息', () { + FakeAsync().run((async) { + expect(async.pendingTimersDebugInfo, []); + // Use `dynamic` to subvert the type checks and access `_FakeAsync` + // internals. + dynamic nonPeriodic = Timer(const Duration(seconds: 1), () {}); + dynamic periodic = + Timer.periodic(const Duration(seconds: 2), (Timer timer) {}); + final debugInfo = async.pendingTimersDebugInfo; + expect(debugInfo.length, 2); + expect( + debugInfo, + debugInfo.contains([ + nonPeriodic.debugInfo, + periodic.debugInfo, + ]), + ); + + // Substrings expected to be included in the first line of + // [Timer.debugInfo]. + final expectedInFirstLine = { + nonPeriodic: [':01.0', 'periodic: false'], + periodic: [':02.0', 'periodic: true'], + }; + + const thisFileName = 'fake_async_test.dart'; + for (final expectedEntry in expectedInFirstLine.entries) { + final debugInfo = expectedEntry.key.debugInfo; + final firstLineEnd = debugInfo.indexOf('\n'); + final firstLine = debugInfo.substring(0, firstLineEnd); + final rest = debugInfo.substring(firstLineEnd + 1); + + for (final expectedValue in expectedEntry.value) { + expect(firstLine, firstLine.contains(expectedValue)); + } + + expect(rest, rest.contains(thisFileName)); + } + }); + }); + }); + + group('timers', () { + test('应该像真实时间一样', () { + return FakeAsync().run((async) { + var timeout = const Duration(minutes: 1); + int counter = 0; + late Timer timer; + timer = Timer(timeout, () { + counter++; + expect( + timer.isActive, + false, + ); + }); + expect(timer.isActive, true); + async.elapse(timeout); + expect(counter, 1); + expect(timer.isActive, false); + }); + }); + }); + }); + } +} diff --git a/ohos/test_quiver/lib/src/testing/equality/equality_test.dart b/ohos/test_quiver/lib/src/testing/equality/equality_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..590f1cb16aab27a0e2747ae24b964e4280082699 --- /dev/null +++ b/ohos/test_quiver/lib/src/testing/equality/equality_test.dart @@ -0,0 +1,397 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.testing.util.equalstester; + +import 'package:quiver/testing/src/equality/equality.dart'; +import 'package:flutter/material.dart'; +import '../../../common/test_page.dart'; + +class EqualityTestPage extends TestPage { + EqualityTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('expectEquals', () { + late _ValidTestObject reference; + late _ValidTestObject equalObject1; + late _ValidTestObject equalObject2; + late _ValidTestObject notEqualObject1; + + // setUp(() { + reference = _ValidTestObject(1, 2); + equalObject1 = _ValidTestObject(1, 2); + equalObject2 = _ValidTestObject(1, 2); + notEqualObject1 = _ValidTestObject(0, 2); + // }); + + test('测试空引用产生错误', () { + try { + expect(null, areEqualityGroups); + fail('Should fail with null reference'); + } catch (e) { + expect(e.toString(), e.toString().contains('Equality Group must not be null')); + } + }); + + test('测试null组名称产生错误', () { + try { + expect({ + 'null': [reference], + null: [reference] + }, areEqualityGroups); + fail('Should fail with null group name'); + } catch (e) { + expect(e.toString(),e.toString().contains('Group name must not be null')); + } + }); + + test('测试null组产生错误', () { + try { + expect({'bad group': null}, areEqualityGroups); + fail('Should fail with null group'); + } catch (e) { + expect(e.toString(), e.toString().contains('Group must not be null')); + } + }); + + test('使用null同时添加多个实例后进行测试', () { + try { + expect({ + 'bad group': [reference, equalObject1, null] + }, areEqualityGroups); + fail('Should fail with null group'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("$reference [group 'bad group', item 1]" + " must be equal to null [group 'bad group', item 3]")); + } + }); + + test('测试仅在单个组中添加不相等的对象', () { + try { + expect({ + 'not equal': [equalObject1, notEqualObject1] + }, areEqualityGroups); + fail('Should get not equal to equal object error'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("$equalObject1 [group 'not equal', item" + " 1] must be equal to $notEqualObject1 [group 'not equal'" + ', item 2]')); + } + }); + + test( + '不使用等于或不等于对象进行测试。这将检查是否正确处理null、不兼容类和自反测试', () { + expect({ + 'single object': [reference] + }, areEqualityGroups); + }); + + test( + '填充相等对象后进行测试。这将检查平等的正确处理,并验证有效对象的hashCode', () { + expect({ + 'all equal': [reference, equalObject1, equalObject2] + }, areEqualityGroups); + }); + + test('测试对象与自身不相等的情况下的正确处理', + () { + Object obj = _NonReflexiveObject(); + try { + expect({ + 'non-reflexive': [obj] + }, areEqualityGroups); + fail('Should get non-reflexive error'); + } catch (e) { + expect(e.toString(), e.toString().contains('$obj must be equal to itself')); + } + }); + + test('测试哈希代码不是幂等的情况的正确处理', () { + Object obj = _InconsistentHashCodeObject(1, 2); + try { + expect({ + 'non-reflexive': [obj] + }, areEqualityGroups); + fail('Should get non-reflexive error'); + } catch (e) { + expect( + e.toString(), + e.toString().contains( + 'the implementation of hashCode of $obj must be idempotent')); + } + }); + + test( + '测试对象错误地测试不兼容类的正确处理', () { + Object obj = _InvalidEqualsIncompatibleClassObject(); + try { + expect({ + 'equals method broken': [obj] + }, areEqualityGroups); + fail('Should get equal to incompatible class error'); + } catch (e) { + expect( + e.toString(), + e.toString().contains('$obj must not be equal to an ' + 'arbitrary object of another class')); + } + }); + + test( + '测试对象与用户所说的应该相等的对象不相等时的正确处理', () { + try { + expect({ + 'non-equal': [reference, notEqualObject1] + }, areEqualityGroups); + fail('Should get not equal to equal object error'); + } catch (e) { + expect( + e.toString(), e.toString().contains("$reference [group 'non-equal', item 1]")); + expect(e.toString(), + e.toString().contains("$notEqualObject1 [group 'non-equal', item 2]")); + } + }); + + test( + '测试无效的hashCode方法,即根据equals方法为相等的对象返回不同值的方法', () { + Object a = _InvalidHashCodeObject(1, 2); + Object b = _InvalidHashCodeObject(1, 2); + try { + expect({ + 'invalid hashcode': [a, b] + }, areEqualityGroups); + fail('Should get invalid hashCode error'); + } catch (e) { + expect( + e.toString(), + e.toString().contains('the hashCode (${a.hashCode}) of $a' + " [group 'invalid hashcode', item 1] must be equal to the" + ' hashCode (${b.hashCode}) of $b')); + } + }); + + test('对称', () { + try { + expect({ + 'broken symmetry': [ + _named('foo')..addPeers(['bar']), + _named('bar') + ] + }, areEqualityGroups); + fail('should fail because symmetry is broken'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("bar [group 'broken symmetry', item 2] " + "must be equal to foo [group 'broken symmetry', item 1]")); + } + }); + + test('传递性在EqualityGroup中断开', () { + try { + expect({ + 'transitivity broken': [ + _named('foo')..addPeers(['bar', 'baz']), + _named('bar')..addPeers(['foo']), + _named('baz')..addPeers(['foo']) + ] + }, areEqualityGroups); + fail('should fail because transitivity is broken'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("bar [group 'transitivity broken', " + "item 2] must be equal to baz [group 'transitivity " + "broken', item 3]")); + } + }); + + test('EqualityGroup中的不相等对象', () { + try { + expect({ + 'unequal objects': [_named('foo'), _named('bar')] + }, areEqualityGroups); + fail('should fail because of unequal objects in the same equality ' + 'group'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("foo [group 'unequal objects', item 1] " + "must be equal to bar [group 'unequal objects', item 2]")); + } + }); + + test('跨均衡组的传递性中断', () { + try { + expect({ + 'transitivity one': [ + _named('foo')..addPeers(['bar']), + _named('bar')..addPeers(['foo', 'x']) + ], + 'transitivity two': [ + _named('baz')..addPeers(['x']), + _named('x')..addPeers(['baz', 'bar']) + ] + }, areEqualityGroups); + fail('should fail because transitivity is broken'); + } catch (e) { + expect( + e.toString(), + e.toString().contains("bar [group 'transitivity one', item 2]" + " must not be equal to x [group 'transitivity two'," + ' item 2]')); + } + }); + + test('均衡器组', () { + expect({ + 'valid groups one': [ + _named('foo')..addPeers(['bar']), + _named('bar')..addPeers(['foo']) + ], + 'valid groups two': [_named('baz'), _named('baz')] + }, areEqualityGroups); + }); + }); +} +} +/// Test class that violates reflexitivity. It is not equal to itself. +class _NonReflexiveObject { + @override + bool operator ==(Object o) => false; + + @override + int get hashCode => 0; +} + +/// Test class with valid equals and hashCode methods. Testers created +/// with instances of this class should always pass. +class _ValidTestObject { + _ValidTestObject(this.aspect1, this.aspect2); + + int aspect1; + int aspect2; + + @override + bool operator ==(Object o) { + if (o is! _ValidTestObject) { + return false; + } + final _ValidTestObject other = o; + if (aspect1 != other.aspect1) { + return false; + } + if (aspect2 != other.aspect2) { + return false; + } + return true; + } + + @override + int get hashCode { + int result = 17; + result = 37 * result + aspect1; + result = 37 * result + aspect2; + return result; + } +} + +///Test class that returns true even if the test object is of the wrong class. +class _InvalidEqualsIncompatibleClassObject { + @override + bool operator ==(Object o) { + return true; + } + + @override + int get hashCode => 0; +} + +/// Test class with inconsistent hashCode method. +class _InconsistentHashCodeObject { + _InconsistentHashCodeObject(this._aspect1, this._aspect2); + + final int _aspect1; + final int _aspect2; + int _hashCode = 0; + + @override + int get hashCode => _hashCode++; + + @override + bool operator ==(Object o) { + if (o is! _InconsistentHashCodeObject) { + return false; + } + final _InconsistentHashCodeObject other = o; + if (_aspect1 != other._aspect1) return false; + if (_aspect2 != other._aspect2) return false; + return true; + } +} + +/// Test class with invalid hashCode method. +class _InvalidHashCodeObject { + _InvalidHashCodeObject(this._aspect1, this._aspect2); + + static int hashCodeSource = 0; + final int _aspect1; + final int _aspect2; + final int _hashCode = hashCodeSource++; + + @override + int get hashCode => _hashCode; + + @override + bool operator ==(Object o) { + if (o is! _InvalidHashCodeObject) { + return false; + } + final _InvalidHashCodeObject other = o; + if (_aspect1 != other._aspect1) return false; + if (_aspect2 != other._aspect2) return false; + return true; + } +} + +_NamedObject _named(String name) => _NamedObject(name); + +class _NamedObject { + _NamedObject(this.name); + + final Set peerNames = {}; + final String name; + + void addPeers(List names) { + peerNames.addAll(names); + } + + @override + bool operator ==(Object obj) { + if (obj is _NamedObject) { + _NamedObject that = obj; + return name == that.name || peerNames.contains(that.name); + } + return false; + } + + @override + int get hashCode => 0; + + @override + String toString() => name; +} diff --git a/ohos/test_quiver/lib/src/time/clock_test.dart b/ohos/test_quiver/lib/src/time/clock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e1f80f94b9adb1191dd70b973613c05264ef277a --- /dev/null +++ b/ohos/test_quiver/lib/src/time/clock_test.dart @@ -0,0 +1,224 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +library quiver.time.clock_test; + +import 'package:quiver/src/time/clock.dart'; +import 'package:flutter/material.dart'; +import '../../common/test_page.dart'; + +Clock from(int y, int m, int d) => Clock.fixed(DateTime(y, m, d)); + +void expectDate(DateTime date, int y, [int m = 1, int d = 1]) { + expect(date, DateTime(y, m, d)); +} + +class ClockTestPage extends TestPage { + ClockTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('clock', () { + late Clock subject; + + // setUp(() { + subject = Clock.fixed(DateTime(2013)); + // }); + + test('应该从系统时钟返回一个非零值', () { + expect(const Clock().now(), const Clock().now() !=null); + }); + + // This test may be flaky on certain systems. I ran it over 10 million + // cycles on my machine without any failures, but that's no guarantee. + test('应该足够接近系统时钟', () { + // At 10ms the test doesn't seem to be flaky. + var epsilon = 10; + expect( + DateTime.now().difference(const Clock().now()).inMilliseconds.abs(), + epsilon); + expect( + DateTime.now().difference(const Clock().now()).inMilliseconds.abs(), + epsilon); + }); + + test('s应返回自定义TimeFunction提供的时间', () { + var time = DateTime(2013); + var fixedClock = Clock(() => time); + expect(fixedClock.now(), DateTime(2013)); + + time = DateTime(2014); + expect(fixedClock.now(), DateTime(2014)); + }); + + test('应返回固定时间', () { + expect(Clock.fixed(DateTime(2013)).now(), DateTime(2013)); + }); + + test('应返回时间Duration ago', () { + expect(subject.agoBy(const Duration(days: 366)), DateTime(2012)); + }); + + test('应该返回时间从现在开始的持续时间', () { + expect(subject.fromNowBy(const Duration(days: 365)), DateTime(2014)); + }); + + test('应该返回以前的时间部分', () { + expect( + subject.ago( + days: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1, + microseconds: 1000), + DateTime(2012, 12, 30, 22, 58, 58, 998)); + }); + + test('应该从现在起返回时间部件', () { + expect( + subject.fromNow( + days: 1, + hours: 1, + minutes: 1, + seconds: 1, + milliseconds: 1, + microseconds: 1000), + DateTime(2013, 1, 2, 1, 1, 1, 2)); + }); + + test('应该返回micros前的时间', () { + expect(subject.microsAgo(1000), DateTime(2012, 12, 31, 23, 59, 59, 999)); + }); + + test('应该从现在起返回时间micros', () { + expect(subject.microsFromNow(1000), DateTime(2013, 1, 1, 0, 0, 0, 1)); + }); + + test('应该返回毫秒前的时间', () { + expect(subject.millisAgo(1000), DateTime(2012, 12, 31, 23, 59, 59, 000)); + }); + + test('应该从现在开始返回时间毫秒', () { + expect(subject.millisFromNow(3), DateTime(2013, 1, 1, 0, 0, 0, 3)); + }); + + test('应该返回秒前的时间', () { + expect(subject.secondsAgo(10), DateTime(2012, 12, 31, 23, 59, 50, 000)); + }); + + test('应该从现在起返回秒的时间', () { + expect(subject.secondsFromNow(3), DateTime(2013, 1, 1, 0, 0, 3, 0)); + }); + + test('应返回分钟前的时间', () { + expect(subject.minutesAgo(10), DateTime(2012, 12, 31, 23, 50, 0, 000)); + }); + + test('应从现在起返回时间分钟', () { + expect(subject.minutesFromNow(3), DateTime(2013, 1, 1, 0, 3, 0, 0)); + }); + + test('应返回小时前的时间', () { + expect(subject.hoursAgo(10), DateTime(2012, 12, 31, 14, 0, 0, 000)); + }); + + test('应从现在起返回时间小时', () { + expect(subject.hoursFromNow(3), DateTime(2013, 1, 1, 3, 0, 0, 0)); + }); + + test('应该返回几天前的时间', () { + expectDate(subject.daysAgo(10), 2012, 12, 22); + }); + + test('应该返回从现在起天的时间', () { + expectDate(subject.daysFromNow(3), 2013, 1, 4); + }); + + test('应在几个月前的同一日期返回时间', () { + expectDate(subject.monthsAgo(1), 2012, 12, 1); + expectDate(subject.monthsAgo(2), 2012, 11, 1); + expectDate(subject.monthsAgo(3), 2012, 10, 1); + expectDate(subject.monthsAgo(4), 2012, 9, 1); + }); + + test('应在同一日期返回从现在起数月的时间', () { + expectDate(subject.monthsFromNow(1), 2013, 2, 1); + expectDate(subject.monthsFromNow(2), 2013, 3, 1); + expectDate(subject.monthsFromNow(3), 2013, 4, 1); + expectDate(subject.monthsFromNow(4), 2013, 5, 1); + }); + + test('应该从2013-05-31到2012-11-30', () { + expectDate(from(2013, 5, 31).monthsAgo(6), 2012, 11, 30); + }); + + test('应该从2013-03-31到2013-02-28(普通年份)', () { + expectDate(from(2013, 3, 31).monthsAgo(1), 2013, 2, 28); + }); + + test('应该从2013-05-31到2013-02-28(普通年份)', () { + expectDate(from(2013, 5, 31).monthsAgo(3), 2013, 2, 28); + }); + + test('应该从2004-03-31到2004-02-29(闰年)', () { + expectDate(from(2004, 3, 31).monthsAgo(1), 2004, 2, 29); + }); + + test('应该从2013-03-31到2013-06-30', () { + expectDate(from(2013, 3, 31).monthsFromNow(3), 2013, 6, 30); + }); + + test('应该从2003-12-31到2004-02-29(跳跃常见)', () { + expectDate(from(2003, 12, 31).monthsFromNow(2), 2004, 2, 29); + }); + + test('应该从2004年2月29日到2003年2月28日', () { + expectDate(from(2004, 2, 29).yearsAgo(1), 2003, 2, 28); + }); + + test('应该从2004-02-29到2003-02-28', () { + expectDate(from(2004, 2, 29).monthsAgo(12), 2003, 2, 28); + }); + + test('应该从2004-02-29到2005-02-28', () { + expectDate(from(2004, 2, 29).yearsFromNow(1), 2005, 2, 28); + }); + + test('应该从2004-02-29到2005-02-28', () { + expectDate(from(2004, 2, 29).monthsFromNow(12), 2005, 2, 28); + }); + + test('应该在几年前的同一天返回', () { + expectDate(subject.yearsAgo(1), 2012, 1, 1); // leap year + expectDate(subject.yearsAgo(2), 2011, 1, 1); + expectDate(subject.yearsAgo(3), 2010, 1, 1); + expectDate(subject.yearsAgo(4), 2009, 1, 1); + expectDate(subject.yearsAgo(5), 2008, 1, 1); // leap year + expectDate(subject.yearsAgo(6), 2007, 1, 1); + expectDate(subject.yearsAgo(30), 1983, 1, 1); + expectDate(subject.yearsAgo(2013), 0, 1, 1); + }); + + test('s应在同一日期返回时间年', () { + expectDate(subject.yearsFromNow(1), 2014, 1, 1); + expectDate(subject.yearsFromNow(2), 2015, 1, 1); + expectDate(subject.yearsFromNow(3), 2016, 1, 1); + expectDate(subject.yearsFromNow(4), 2017, 1, 1); + expectDate(subject.yearsFromNow(5), 2018, 1, 1); + expectDate(subject.yearsFromNow(6), 2019, 1, 1); + expectDate(subject.yearsFromNow(30), 2043, 1, 1); + expectDate(subject.yearsFromNow(1000), 3013, 1, 1); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/.gitignore b/ohos/test_quiver/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_quiver/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_quiver/ohos/AppScope/app.json5 b/ohos/test_quiver/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..1e9bdddccad6844cf848c1529e3016934f5b9c71 --- /dev/null +++ b/ohos/test_quiver/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_quiver", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_quiver/ohos/AppScope/resources/base/element/string.json b/ohos/test_quiver/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..1a64c4ae5aebd49674987a01fed9bed66fe3efaf --- /dev/null +++ b/ohos/test_quiver/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_quiver" + } + ] +} diff --git a/ohos/test_quiver/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_quiver/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_quiver/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_quiver/ohos/build-profile.json5 b/ohos/test_quiver/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..4c313a1c1bcdce3df4fe2858ba52871d4afa2aef --- /dev/null +++ b/ohos/test_quiver/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_quiver.cer", + "storePassword": "0000001BA7BC329A0460E9E7DD7A35FA0348E024D99D2D1912D721348C0DCE662D4A2B43DB3BBE3254DDAB", + "keyAlias": "debugKey", + "keyPassword": "0000001B4862690F5783E33974BE2D136D3CBE1FC93195320BB3574B7C4284367958DA7617EEAA5EDAE77F", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_quiver.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_quiver.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_quiver/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_quiver/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_quiver/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_quiver/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_quiver/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_quiver/ohos/dependencies/rollup.tgz b/ohos/test_quiver/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_quiver/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_quiver/ohos/dta/icudtl.dat b/ohos/test_quiver/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_quiver/ohos/dta/icudtl.dat differ diff --git a/ohos/test_quiver/ohos/entry/.gitignore b/ohos/test_quiver/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/build-profile.json5 b/ohos/test_quiver/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_quiver/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/hvigorfile.ts b/ohos/test_quiver/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_quiver/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_quiver/ohos/entry/oh-package.json5 b/ohos/test_quiver/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_quiver/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_quiver/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_quiver/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_quiver/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_quiver/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/module.json5 b/ohos/test_quiver/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_quiver/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_quiver/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_quiver/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_quiver/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_quiver/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3abf18c41c58c933308c244a875bf383856e103e --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]}] \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..0f19b46a87e3b631911a34e2173a7d42aea90464 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..7ab6c1c31030be0a460075833a1864881a3b5422 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_quiver/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_quiver/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/module.json5 b/ohos/test_quiver/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_quiver/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_quiver/ohos/har/flutter_embedding.har b/ohos/test_quiver/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_quiver/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_quiver/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_quiver/ohos/har/flutter_embedding.har.release.10 b/ohos/test_quiver/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_quiver/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_quiver/ohos/har/flutter_embedding.har.release.9 b/ohos/test_quiver/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_quiver/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_quiver/ohos/har/libflutter.so.debug.10 b/ohos/test_quiver/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_quiver/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_quiver/ohos/har/libflutter.so.release.10 b/ohos/test_quiver/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_quiver/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_quiver/ohos/hvigor/hvigor-config.json5 b/ohos/test_quiver/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_quiver/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_quiver/ohos/hvigor/hvigor-wrapper.js b/ohos/test_quiver/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_quiver/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_quiver/ohos/hvigorfile.ts b/ohos/test_quiver/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_quiver/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_quiver/ohos/hvigorw b/ohos/test_quiver/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_quiver/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_quiver/ohos/hvigorw.bat b/ohos/test_quiver/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_quiver/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_quiver/ohos/oh-package-lock.json5 b/ohos/test_quiver/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_quiver/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_quiver/ohos/oh-package.json5 b/ohos/test_quiver/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_quiver/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_quiver/pubspec.yaml b/ohos/test_quiver/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..1c168bf24168dea6bc854bf275e1219ad60f48cd --- /dev/null +++ b/ohos/test_quiver/pubspec.yaml @@ -0,0 +1,31 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_quiver +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + quiver: 3.2.1 +dev_dependencies: + lints: ^1.0.0 + test: ^1.16.0 +flutter: + uses-material-design: true \ No newline at end of file diff --git a/ohos/test_sqflite/.gitignore b/ohos/test_sqflite/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_sqflite/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_sqflite/.metadata b/ohos/test_sqflite/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..6417c95176bd78f8e0ccc9d9c01e8c59bc696c77 --- /dev/null +++ b/ohos/test_sqflite/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: android + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_sqflite/README.md b/ohos/test_sqflite/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_sqflite/analysis_options.yaml b/ohos/test_sqflite/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_sqflite/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_sqflite/lib/common/base_page.dart b/ohos/test_sqflite/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..987585c34978cebd1560dbba1ff3f5fb542512ef --- /dev/null +++ b/ohos/test_sqflite/lib/common/base_page.dart @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_sqflite/lib/common/item_widget.dart b/ohos/test_sqflite/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_sqflite/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_sqflite/lib/common/main_item_widget.dart b/ohos/test_sqflite/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_sqflite/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_sqflite/lib/common/test_model_app.dart b/ohos/test_sqflite/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_sqflite/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_sqflite/lib/common/test_page.dart b/ohos/test_sqflite/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_sqflite/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_sqflite/lib/common/test_route.dart b/ohos/test_sqflite/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_sqflite/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_sqflite/lib/div_page/control_with_result.dart b/ohos/test_sqflite/lib/div_page/control_with_result.dart new file mode 100644 index 0000000000000000000000000000000000000000..9b35f25c15c9bffffe5c124cf5071621027638c6 --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/control_with_result.dart @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +class ControlWithResult extends StatefulWidget { + const ControlWithResult({super.key, required this.title, required this.description, required this.func}); + + final String title; + + final String description; + + final Future Function() func; + + @override + State createState() => ControlWithResultState(); +} + +class ControlWithResultState extends State { + @override + Widget build(BuildContext context) { + return Container( + padding: const EdgeInsets.only(top: 5, bottom: 5), + decoration: const BoxDecoration(border: Border(bottom: BorderSide(color: Colors.grey, width: 0.5))), + child: Column( + children: [ + Row( + children: [ + Container( + // width: 150, + margin: const EdgeInsets.only(right: 10), + child: TextButton( + onPressed: () => runTest(), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.blue), + ), + child: const Text('运行', maxLines: 1, style: TextStyle(color: Colors.white)))), + Expanded(child: Text(widget.title, maxLines: 1)), + Visibility( + visible: isRun, + child: const CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation(Colors.blue), // 更改颜色为蓝色 + )), + Container( + // width: 150, + margin: const EdgeInsets.only(right: 10), + child: TextButton( + onPressed: () => changeShow(), + style: ButtonStyle( + backgroundColor: MaterialStateProperty.all(Colors.blue), + ), + child: Text(isShow ? '隐藏信息' : '展开信息', maxLines: 1, style: const TextStyle(color: Colors.white)))), + ], + ), + Visibility( + visible: widget.description.isNotEmpty && isShow, + child: Row( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text('预期:', style: TextStyle(fontSize: 20)), + Text(widget.description), + ], + ), + ], + )), + Row( + children: [ + Visibility( + visible: resultData.isNotEmpty && isShow, child: const Text('结果: ', style: TextStyle(fontSize: 20))), + ], + ), + Visibility( + visible: resultData.isNotEmpty && isShow, + child: SizedBox(width: MediaQuery.of(context).size.width, child: Text(resultData))), + ], + ), + ); + } + + /// 是否正在运行中 + bool isRun = false; + + /// 展开状态 + bool isShow = false; + + /// 结果信息 + String resultData = ''; + + void changeShow() { + isShow = !isShow; + setState(() {}); + } + + Future runTest() async { + if (isRun == true) { + return; + } + if (mounted) { + setState(() { + isRun = true; + resultData = ''; + }); + } + + final timer = Timer.periodic(const Duration(seconds: 20), (timer) { + print('20s超时取消定时器'); + timer.cancel(); + if (mounted) { + setState(() { + isRun = false; + resultData = '20s超时异常'; + }); + } + return; + }); + try { + final result = await widget.func(); + isShow = true; + timer.cancel(); + if (mounted) { + setState(() { + isRun = false; + if (result != null) { + resultData = result.toString(); + } else { + resultData = '无返回值'; + } + }); + } + } catch (e) { + timer.cancel(); + if (mounted) { + setState(() { + isRun = false; + resultData = '出现异常: $e'; + }); + } + } + } +} diff --git a/ohos/test_sqflite/lib/div_page/data_base.dart b/ohos/test_sqflite/lib/div_page/data_base.dart new file mode 100644 index 0000000000000000000000000000000000000000..13246197eb2f32bc3923f15ca1f925f0a87dabe6 --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/data_base.dart @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +class LocalDataBase { + LocalDataBase(this.dbName, this.tbName); + + /// 数据库的名字 + final String dbName; + + /// 表的名字 + final String tbName; +} diff --git a/ohos/test_sqflite/lib/div_page/div_page.dart b/ohos/test_sqflite/lib/div_page/div_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..2e92b82a06d32408e9c85573dd4cd73d86aa0b1c --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/div_page.dart @@ -0,0 +1,569 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; +import 'dart:convert'; +import 'dart:io'; + +import 'package:flutter/material.dart'; +import 'package:test_sqflite/div_page/sql_helper.dart'; +import 'package:test_sqflite/sqflite/lib/sqflite.dart'; + +import 'control_with_result.dart'; +import 'global.dart'; +import 'input_box.dart'; + +class DivPage extends StatefulWidget { + const DivPage({super.key}); + + @override + State createState() => DivPageState(); +} + +class DivPageState extends State { + String dataBaseName = ''; + + String tableName = ''; + + /// 数据库的名称 + final TextEditingController dataBaseNameController = TextEditingController(); + + /// 数据库的表名 + final TextEditingController tableNameController = TextEditingController(); + + /// 列值, 如果是用作插入数据时, 格式需要转化为json + final TextEditingController dataController = TextEditingController(); + + /// 列名 + final TextEditingController poiNameController = TextEditingController(); + + /// 替换的值, 仅更新时使用 + final TextEditingController poiDataController = TextEditingController(); + + /// 增加属性, 仅更新时使用 + final TextEditingController addNewPropertyController = TextEditingController(); + + /// 删除属性, 仅更新时使用 + final TextEditingController deletePropertyController = TextEditingController(); + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + iconTheme: const IconThemeData(color: Colors.white), + title: const Text('SqfLite测试', style: TextStyle(color: Colors.white)), + ), + body: ListView( + children: [ + Padding( + padding: const EdgeInsets.only(top: 10), + child: Text( + '当前操作数据库: $dataBaseName', + style: const TextStyle(fontSize: 16), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 10), + child: Text( + '当前操作的表: $tableName', + style: const TextStyle(fontSize: 16), + ), + ), + Padding( + padding: const EdgeInsets.only(top: 10), + child: Text( + '当前数据库id(鸿蒙下才有): $hmDBCount', + style: const TextStyle(fontSize: 16), + ), + ), + // SizedBox( + // child: Column( + // children: [ + // InputBoxForSqfLite( + // controller: dataBaseNameController, + // title: '当前操作数据库', + // ), + // InputBoxForSqfLite( + // controller: tableNameController, + // title: '当前操作的表', + // ), + // ], + // ), + // ), + // Container( + // // width: 150, + // margin: const EdgeInsets.only(right: 10), + // child: TextButton( + // onPressed: () => insertDefault(), + // style: ButtonStyle( + // backgroundColor: MaterialStateProperty.all(Colors.blue), + // ), + // child: const Text('填入默认数据库信息', maxLines: 1, style: TextStyle(color: Colors.white)))), + ControlWithResult(title: '打开$dataBaseNameConst数据库', description: '打开数据库成功, 并成功返回id', func: () async => createDataBase()), + // ControlWithResult(title: '查询$dataBaseName数据库', description: 'defaultDataBase数据库存在/不存在', func: () async => checkDataBase()), + ControlWithResult(title: '删除$dataBaseNameConst数据库', description: '删除defaultDataBase数据库成功', func: () async => deleteDataBase()), + + ControlWithResult(title: '创建$tableNameConst表, 带有 id,name,year数据', description: '创建defaultTable表成功', func: () async => createTable()), + ControlWithResult(title: '查询$tableNameConst表', description: 'defaultTable表已存在/不存在', func: () async => checkTable()), + ControlWithResult(title: '删除$tableNameConst表', description: '删除defaultTable表成功', func: () async => deleteTable()), + + // InputBoxForSqfLite( + // controller: addNewPropertyController, + // title: '增加属性\n(属性名 类型)', + // ), + // ControlWithResult(title: '增加属性', description: '有返回值', func: () async => addNewProperty()), + // InputBoxForSqfLite( + // controller: deletePropertyController, + // title: '删除属性\n(属性名 类型)', + // ), + // ControlWithResult(title: '删除属性', description: '有返回值', func: () async => deleteProperty()), + + // Visibility( + // visible: localDataBase != null, + // child: SizedBox( + // child: Column( + // children: [ + // InputBoxForSqfLite( + // controller: dataController, + // title: '增/查\n(json)', + // ), + // InputBoxForSqfLite( + // controller: poiNameController, + // title: '列名\n(指定位置)', + // ), + // InputBoxForSqfLite( + // controller: poiDataController, + // title: '输入值\n(用,分隔)', + // ), + // ], + // ), + // ), + // ), + + // const Padding( + // padding: EdgeInsets.only(top: 10), + // child: Text( + // '数据格式示例: {"id":2,"name":"hi","year":2000}', + // style: TextStyle(fontSize: 16), + // ), + // ), + ControlWithResult( + title: '${tableName.isNotEmpty ? '' : '(还没有指定表) '}插入{"id":2,"name":"hi","year":2000}', + description: ' 1. 可以返回插入的行id\n 2. 没有创建数据库时提示未打开数据库\n 3. 没有创建表时提示未加载表', + func: () async => insertData()), + ControlWithResult( + title: '${tableName.isNotEmpty ? '' : '(还没有指定表) '}查询{"id":2}', + description: ' 1. 有数据时可以获取到id:2的数据, 删除数据后为[]\n 2. 没有创建数据库时提示未打开数据库\n 3. 没有创建表时提示未加载表', + func: () async => queryData()), + ControlWithResult( + title: '${tableName.isNotEmpty ? '' : '(还没有指定表) '}修改id:2 -> {"name":"hello","year":2023}', + description: ' 1. 可以返回修改行数\n 2. 没有创建数据库时提示未打开数据库\n 3. 没有创建表时提示未加载表', + func: () async => updateData()), + ControlWithResult( + title: '${tableName.isNotEmpty ? '' : '(还没有指定表) '}删除id:2', + description: ' 1. 可以返回删除行数\n 2. 没有创建数据库时提示未打开数据库\n 3. 没有创建表时提示未加载表', + func: () async => deleteData()), + ], + ), + ); + } + + Database? localDataBase; + + // todo 下面是鸿蒙的数据库方法 + + /// 当前操作的鸿蒙数据库id + int hmDBCount = -1; + + /// 创建数据库 + Future hmCreateDataBase(String dbName) async { + String log = ''; + if (dbName == dataBaseName) { + log += '打开数据库成功, id: $hmDBCount\n'; + return log; + } + + final result = await SqlHelper.run('openDatabase', {'path': ' /data/user/0/com.example.test_sqflite/databases/$dbName', 'singleInstance': true}); + + try { + hmDBCount = extractIdFromJson(result.toString()); + log += '打开数据库成功, id: $hmDBCount\n'; + dataBaseName = dbName; + setState(() {}); + } catch (e) { + log += '打开数据库失败$result\n'; + log += '$e\n'; + } + + return log; + } + + int extractIdFromJson(String jsonString) { + // 使用正则表达式匹配 "id": 后面的数字 + var match = RegExp(r'"id":(\d+)').firstMatch(jsonString); + if (match != null) { + return int.tryParse(match[1] ?? '') ?? 0; + } else { + throw Exception('无法从JSON字符串中提取id'); + } + } + + /// 获取数据库路径 + Future hmGetDatabasesPath() async { + String log = ''; + final result = await SqlHelper.run('getDatabasesPath'); + log += '获取数据库路径成功:$result\n'; + + return log; + } + + /// 查询数据库 + Future hmCheckDataBase(String dbName) async { + String log = ''; + final result = await SqlHelper.run('databaseExists', {'path': '/data/user/0/com.example.test_sqflite/databases/$dbName'}); + log += '查询数据库成功\n'; + log += result ? '$dbName数据库存在' : '$dbName数据库不存在'; + + return log; + } + + /// 删除数据库 + Future hmDeleteDataBase(String dbName) async { + String log = ''; + await SqlHelper.run('deleteDatabase', {'path': '/data/user/0/com.example.test_sqflite/databases/$dbName'}); + log += '删除$dataBaseNameConst数据库成功\n'; + hmDBCount = -1; + dataBaseName = ''; + tableName = ''; + setState(() {}); + return log; + } + + /// 创建表 + Future hmCreateTable(String tbName) async { + String log = ''; + if (hmDBCount < 0) { + return '未打开数据库'; + } + + if (tbName == tableName) { + log += '创建$tbName表成功\n'; + return log; + } + + final result = await SqlHelper.run( + 'execute', {'sql': 'CREATE TABLE IF NOT EXISTS $tbName (id INTEGER PRIMARY KEY, name TEXT, year INTEGER)', 'id': hmDBCount}); + log += '创建表成功$result\n'; + tableName = tbName; + setState(() {}); + return log; + } + + /// 删除表 + Future hmDeleteTable(String tbName) async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + String log = ''; + await SqlHelper.run('execute', {'sql': 'DROP TABLE $tbName', 'id': hmDBCount}); + log += '删除$tbName表成功\n'; + tableName = ''; + setState(() {}); + return log; + } + + /// 检查表 + Future hmCheckTable(String tbName) async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '$tbName表不存在'; + } + String log = ''; + final result = await SqlHelper.run('query', {'sql': 'SELECT * FROM $tbName', 'id': hmDBCount}); + final txt = result.toString(); + + if (txt.contains('checkTable') && txt.contains('true')) { + log += '$tbName表已存在'; + } else { + log += '$tbName表不存在'; + } + + return log; + } + + /// 插入数据 + Future hmInsertData() async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + + String log = ''; + final result = await SqlHelper.run('insert', { + 'sql': 'INSERT INTO $tableName (id, name, year) VALUES (?, ?, ?)', + 'arguments': [2, 'hi', 2000], + 'id': hmDBCount + }); + log += '插入数据成功,行id: $result'; + + return log; + } + + /// 查询数据 + Future hmQueryData() async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + String log = ''; + final result = await SqlHelper.run('query', { + 'sql': 'SELECT * FROM $tableName WHERE id = ?', + 'arguments': [2], + 'id': hmDBCount + }); + log += result.toString(); + + return log; + } + + /// 修改数据 + Future hmUpdateData() async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + String log = ''; + final result = await SqlHelper.run('update', { + 'sql': 'UPDATE $tableName SET name = ?, year = ? WHERE id = ?', + 'arguments': ['hello', 2023, 2], + 'id': hmDBCount + }); + log += '修改行数: $result'; + + return log; + } + + /// 删除数据 + Future hmDeleteData() async { + if (hmDBCount < 0) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + String log = ''; + final result = await SqlHelper.run('update', { + 'sql': 'DELETE FROM $tableName WHERE id = ?', + 'arguments': [2], + 'id': hmDBCount + }); + log += '删除行数: $result'; + + return log; + } + + // todo 下面是android的方法 + /// 创建数据库 + Future createDataBase() async { + if (Platform.isAndroid) { + String log = ''; + localDataBase = await openDatabase(dataBaseNameConst, version: 1, onCreate: (db, version) async {}); + print('---------- $log'); + log += '打开数据库成功\n'; + dataBaseName = dataBaseNameConst; + setState(() {}); + return log; + } else { + return await hmCreateDataBase(dataBaseNameConst); + } + } + + /// 检查数据库 + Future checkDataBase() async { + if (Platform.isAndroid) { + final result = await databaseExists(dataBaseNameConst); + + return result ? '$dataBaseNameConst数据库存在' : '$dataBaseNameConst数据库不存在'; + } else { + return await hmCheckDataBase(dataBaseNameConst); + } + } + + /// 删除数据库 + Future deleteDataBase() async { + if (Platform.isAndroid) { + await deleteDatabase(dataBaseNameConst); + localDataBase = null; + dataBaseName = ''; + tableName = ''; + setState(() {}); + return '删除$dataBaseNameConst数据库成功'; + } else { + return await hmDeleteDataBase(dataBaseNameConst); + } + } + + /// 创建表 + Future createTable() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + String log = ''; + await localDataBase!.execute('CREATE TABLE IF NOT EXISTS $tableNameConst (id INTEGER PRIMARY KEY, name TEXT, year INTEGER)'); + log += '创建$tableNameConst表成功\n'; + tableName = tableNameConst; + setState(() {}); + return log; + } else { + return await hmCreateTable(tableNameConst); + } + } + + /// 删除表 + Future deleteTable() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + await localDataBase!.execute('DROP TABLE $tableNameConst'); + tableName = ''; + setState(() {}); + return '删除$tableNameConst表成功'; + } else { + return await hmDeleteTable(tableNameConst); + } + } + + /// 检查表 + Future checkTable() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '$tableName表不存在'; + } + String log = ''; + try { + await localDataBase!.query(tableName); + log += '$tableNameConst表已存在\n'; + } catch (e) { + log += '$tableNameConst表不存在\n'; + } + + return log; + } else { + return await hmCheckTable(tableName); + } + } + + /// 插入数据 + Future insertData() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + + Map data = {}; + try { + data = json.decode('{"id":2,"name":"hi","year":2000}') as Map; + } catch (e) { + return 'json转化出错: $e'; + } + + final id = await localDataBase!.insert(tableName, data); + + return '插入数据成功,行id: $id'; + } else { + return await hmInsertData(); + } + } + + /// 查询数据 + Future queryData() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + final data = await localDataBase!.query(tableName, where: 'id = ?', whereArgs: [2]); + + return json.encode(data.toList()); + } else { + return await hmQueryData(); + } + } + + /// 修改数据 + Future updateData() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + Map data = {}; + try { + data = json.decode('{"name":"hello","year":2023}') as Map; + } catch (e) { + return 'json转化出错: $e'; + } + + final id = await localDataBase!.update(tableName, data, where: 'id = ?', whereArgs: [2]); + + return '修改行数: $id'; + } else { + return await hmUpdateData(); + } + } + + /// 删除数据 + Future deleteData() async { + if (Platform.isAndroid) { + if (localDataBase == null) { + return '未打开数据库'; + } + if (tableName.isEmpty) { + return '未加载表'; + } + final id = await localDataBase!.delete(tableName, where: 'id = ?', whereArgs: [2]); + + return '删除行数: $id'; + } else { + return await hmDeleteData(); + } + } +} diff --git a/ohos/test_sqflite/lib/div_page/global.dart b/ohos/test_sqflite/lib/div_page/global.dart new file mode 100644 index 0000000000000000000000000000000000000000..e829db098cd3e75d341000b2680f27b3e5691999 --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/global.dart @@ -0,0 +1,18 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/// 默认的数据库名和表名 +const String dataBaseNameConst = 'defaultDataBase'; +const String tableNameConst = 'defaultTable'; \ No newline at end of file diff --git a/ohos/test_sqflite/lib/div_page/input_box.dart b/ohos/test_sqflite/lib/div_page/input_box.dart new file mode 100644 index 0000000000000000000000000000000000000000..ce94308c00be1dadd426d29dbac8164aeb3d680c --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/input_box.dart @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +class InputBoxForSqfLite extends StatefulWidget { + const InputBoxForSqfLite({super.key, required this.controller, required this.title}); + + final TextEditingController controller; + final String title; + + @override + State createState() => InputBoxForSqfLiteState(); +} + +class InputBoxForSqfLiteState extends State { + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.only(top: 5), + child: Row( + children: [ + SizedBox(width: 120, child: Text('${widget.title}:')), + Expanded( + child: Container( + decoration: const BoxDecoration(color: CupertinoColors.systemGrey5), + child: TextField( + controller: widget.controller, + decoration: const InputDecoration(border: InputBorder.none), + ), + ), + ) + ], + ), + ); + } +} diff --git a/ohos/test_sqflite/lib/div_page/sql_helper.dart b/ohos/test_sqflite/lib/div_page/sql_helper.dart new file mode 100644 index 0000000000000000000000000000000000000000..2ffa6ac7a239638b719b5ca7c670a6123e8a6d39 --- /dev/null +++ b/ohos/test_sqflite/lib/div_page/sql_helper.dart @@ -0,0 +1,130 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:test_sqflite/sqflite/lib/src/ohos_extension.dart'; +import 'package:test_sqflite/sqflite/lib/src/messages.g.dart' as messages; + +abstract class SqlHelper { + static final messages.SqfliteApi _api = messages.SqfliteApi(); + + /// Invoke a native method + static Future run(String method, [Object? arguments]) async { + T data; + switch (method) { + case Constant.METHOD_GET_PLATFORM_VERSION: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.getPlatformVersion(arguments) as T; + break; + } + case Constant.METHOD_CLOSE_DATABASE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onCloseDatabaseCall(arguments) as T; + break; + } + case Constant.METHOD_QUERY: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onQueryCall(arguments) as T; + break; + } + case Constant.METHOD_INSERT: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onInsertCall(arguments) as T; + break; + } + case Constant.METHOD_UPDATE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onUpdateCall(arguments) as T; + break; + } + case Constant.METHOD_EXECUTE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onExecuteCall(arguments) as T; + break; + } + case Constant.METHOD_OPEN_DATABASE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onOpenDatabaseCall(arguments) as T; + break; + } + case Constant.METHOD_BATCH: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onBatchCall(arguments) as T; + break; + } + case Constant.METHOD_OPTIONS: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onOptionsCall(arguments) as T; + break; + } + case Constant.METHOD_GET_DATABASES_PATH: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + // data = '/data/storage/el2/database' as T; + data = await _api.onGetDatabasesPathCall(arguments) as T; + break; + } + case Constant.METHOD_DELETE_DATABASE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onDeleteDatabaseCall(arguments) as T; + break; + } + case Constant.METHOD_DEBUG: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onDebugCall(arguments) as T; + break; + } + case Constant.METHOD_QUERY_CURSOR_NEXT: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onQueryCursorNextCall(arguments) as T; + break; + } + case Constant.METHOD_DATABASE_EXISTS: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onDatabaseExistsCall(arguments) as T; + break; + } + case Constant.METHOD_DEBUG_MODE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onDebugModeCall(arguments) as T; + break; + } + case Constant.METHOD_ANDROID_SET_LOCALE: + { + print('---------- 新的:flutter调用鸿蒙$method通道,数据 -> ${arguments.toString()} \n'); + data = await _api.onSetLocaleCall(arguments) as T; + break; + } + default: + data = ' ---------- 新的:未适配的通道 $method \n' as T; + } + + print('---------- 新的:鸿蒙调用成功, $method取到返回的数据 -> $data \n'); + return data ?? '' as T; + } +} diff --git a/ohos/test_sqflite/lib/main.dart b/ohos/test_sqflite/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..0abb8c95f93ee48a3d90146b1bef7815e7eac241 --- /dev/null +++ b/ohos/test_sqflite/lib/main.dart @@ -0,0 +1,80 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_sqflite/src/no_flutter_main.dart'; +import 'package:test_sqflite/src/sqflite_dev_test.dart'; +import 'package:test_sqflite/src/sqflite_impl_test.dart'; +import 'package:test_sqflite/src/sqflite_macos_impl_test.dart'; +import 'package:test_sqflite/src/sqflite_open_test.dart'; +import 'package:test_sqflite/src/sqflite_test.dart'; +import 'package:test_sqflite/src/sql_test.dart'; +import 'package:test_sqflite/src/sqlite_api_test.dart'; +import 'package:test_sqflite/src/src_mixin_factory_test.dart'; +import 'package:test_sqflite/src/src_mixin_test.dart'; + +import 'common/base_page.dart'; +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; +import 'div_page/div_page.dart'; +import 'package:sqflite/sqflite.dart'; + +void main() { + // final app = [ + // MainItem('自定义测试界面', const DivPage()), + // // MainItem('no_flutter_main', no_flutter_mainTestPage('no_flutter_main')), + // MainItem('sqflite_dev_test', sqflite_devTestPage('sqflite_dev_test')), + // MainItem('sqflite_impl_test', sqflite_implTestPage('sqflite_impl_test')), + // // MainItem('sqflite_macos_impl_test', sqflite_macos_implTestPage('sqflite_macos_impl_test')), + // MainItem('sqflite_open_test', sqflite_openTestPage('sqflite_open_test')), + // MainItem('sqflite_test', sqfliteTestPage('sqflite_test')), + // MainItem('sql_test', sqlTestPage('sql_test')), + // MainItem('sqlite_api_test', sqlite_apiTestPage('sqlite_api_test')), + // MainItem('src_mixin_factory_test', src_mixin_factoryTestPage('src_mixin_factory_test')), + // MainItem('src_mixin_test', SrcMixinTestPage('src_mixin_test')), + // ]; + + // runApp(TestModelApp(appName: 'SqfLite', data: app)); + runApp(MainApp(appName: 'SqfLite')); +} + +/// 基础app框架 +class MainApp extends StatefulWidget { + MainApp({Key? key, required this.appName}) : super(key: key) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + @override + State createState() => MainAppState(); +} + +class MainAppState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: const DivPage(), + ); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/CHANGELOG.md b/ohos/test_sqflite/lib/sqflite/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_sqflite/lib/sqflite/LICENSE b/ohos/test_sqflite/lib/sqflite/LICENSE new file mode 100644 index 0000000000000000000000000000000000000000..5385068f4185ae407a9bb1900c11585bce96cbb1 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/LICENSE @@ -0,0 +1,25 @@ +BSD 2-Clause License + +Copyright (c) 2019, Alexandre Roux Tekartik +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/ohos/test_sqflite/lib/sqflite/analysis_options.yaml b/ohos/test_sqflite/lib/sqflite/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..af4618aadabd743317fb05bcdd2ccf4b7045c21a --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/analysis_options.yaml @@ -0,0 +1,118 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +include: package:flutter_lints/flutter.yaml + +# Until there are meta linter rules, each desired lint must be explicitly enabled. +# See: https://github.com/dart-lang/linter/issues/288 +# +# For a list of lints, see: http://dart-lang.github.io/linter/lints/ +# See the configuration guide for more +# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer +# +# NOTE: Please keep this file in sync with +# https://github.com/flutter/flutter/blob/master/analysis_options.yaml + +analyzer: + language: + strict-casts: true + strict-inference: true + + errors: + # treat missing required parameters as a warning (not a hint) + missing_required_param: warning + # treat missing returns as a warning (not a hint) + missing_return: warning + # allow having TODOs in the code + todo: ignore + # Ignore errors like + # 'super_goes_last' is a deprecated lint rule and should not be used • included_file_warning + included_file_warning: ignore + +linter: + rules: + - always_declare_return_types + - avoid_dynamic_calls + - avoid_empty_else + - avoid_relative_lib_imports + - avoid_shadowing_type_parameters + - avoid_slow_async_io + - avoid_types_as_parameter_names + - await_only_futures + - camel_case_extensions + - camel_case_types + - cancel_subscriptions + - curly_braces_in_flow_control_structures + - directives_ordering + - empty_catches + - hash_and_equals + - iterable_contains_unrelated_type + - list_remove_unrelated_type + - no_adjacent_strings_in_list + - no_duplicate_case_values + - non_constant_identifier_names + - omit_local_variable_types + - package_api_docs + - package_prefixed_library_names + - prefer_generic_function_type_aliases + - prefer_is_empty + - prefer_is_not_empty + - prefer_iterable_whereType + - prefer_single_quotes + - prefer_typing_uninitialized_variables + - sort_child_properties_last + - test_types_in_equals + - throw_in_finally + - unawaited_futures + - unnecessary_null_aware_assignments + - unnecessary_statements + - unrelated_type_equality_checks + - unsafe_html + - valid_regexps + + - constant_identifier_names + - control_flow_in_finally + - empty_statements + - implementation_imports + - overridden_fields + - package_names + - prefer_const_constructors + - prefer_initializing_formals + - prefer_void_to_null + # + - always_require_non_null_named_parameters + - annotate_overrides + - avoid_init_to_null + - avoid_null_checks_in_equality_operators + - avoid_return_types_on_setters + - empty_constructor_bodies + - library_names + - library_prefixes + - prefer_adjacent_string_concatenation + - prefer_collection_literals + - prefer_contains + - slash_for_doc_comments + - type_init_formals + - unnecessary_const + - unnecessary_new + - unnecessary_null_in_if_null_operators + - use_rethrow_when_possible + # === doc rules === + - public_member_api_docs + # + - prefer_final_locals + - sort_constructors_first + - sort_unnamed_constructors_first + diff --git a/ohos/test_sqflite/lib/sqflite/android/.gitignore b/ohos/test_sqflite/lib/sqflite/android/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..c6c681fe64e3f1bd4c715bf98e18877b6d27439c --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/.gitignore @@ -0,0 +1,12 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures + +gradle-wrapper.jar +/gradlew +/gradlew.bat diff --git a/ohos/test_sqflite/lib/sqflite/android/build.gradle b/ohos/test_sqflite/lib/sqflite/android/build.gradle new file mode 100644 index 0000000000000000000000000000000000000000..28870010c8847822b8ba27e16506dd6a57ca9d34 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/build.gradle @@ -0,0 +1,55 @@ +group 'com.tekartik.sqflite' +version '1.0-SNAPSHOT' + +buildscript { + repositories { + google() + mavenCentral() + } + + dependencies { + classpath 'com.android.tools.build:gradle:7.4.2' + } +} + +rootProject.allprojects { + repositories { + google() + mavenCentral() + } +} + +allprojects { + gradle.projectsEvaluated { + tasks.withType(JavaCompile) { + options.compilerArgs << "-Xlint:unchecked" << "-Xlint:deprecation" + } + } +} + +apply plugin: 'com.android.library' + +android { + // Conditional for compatibility with AGP <4.2. + if (project.android.hasProperty("namespace")) { + namespace 'com.tekartik.sqflite' + } + compileSdkVersion 33 + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + + defaultConfig { + minSdkVersion 16 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + lintOptions { + disable 'InvalidPackage' + } +} + +dependencies { + testImplementation 'junit:junit:4.13.2' +} diff --git a/ohos/test_sqflite/lib/sqflite/android/gradle.properties b/ohos/test_sqflite/lib/sqflite/android/gradle.properties new file mode 100644 index 0000000000000000000000000000000000000000..2bd6f4fda009061e5236b75f39ee67fd4c1d8a5b --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/gradle.properties @@ -0,0 +1,2 @@ +org.gradle.jvmargs=-Xmx1536M + diff --git a/ohos/test_sqflite/lib/sqflite/android/gradle/wrapper/gradle-wrapper.properties b/ohos/test_sqflite/lib/sqflite/android/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000000000000000000000000000000000000..128a4044196f7fd827d62b387c2545798054a739 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Fri Apr 05 14:03:42 CEST 2019 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip diff --git a/ohos/test_sqflite/lib/sqflite/android/settings.gradle b/ohos/test_sqflite/lib/sqflite/android/settings.gradle new file mode 100644 index 0000000000000000000000000000000000000000..0ba7ef01066c21c0419c949090bd8c5391e2ab7c --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/settings.gradle @@ -0,0 +1 @@ +rootProject.name = 'sqflite' diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/AndroidManifest.xml b/ohos/test_sqflite/lib/sqflite/android/src/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..5406b3daa734f71a8622646d5e3f16d995ba1bd0 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/AndroidManifest.xml @@ -0,0 +1,3 @@ + + diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Constant.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Constant.java new file mode 100644 index 0000000000000000000000000000000000000000..9b82ac1421cc99634b5a79cc5ccb78b0a62954ec --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Constant.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +/** + * Constants between dart & Java world + */ + +public class Constant { + + // Can be used as the name MethodChannel or to register with + static final public String PLUGIN_KEY = "com.tekartik.sqflite"; + + static final public String METHOD_GET_PLATFORM_VERSION = "getPlatformVersion"; + static final public String METHOD_GET_DATABASES_PATH = "getDatabasesPath"; + static final public String METHOD_DEBUG = "debug"; + static final public String METHOD_OPTIONS = "options"; + static final public String METHOD_OPEN_DATABASE = "openDatabase"; + static final public String METHOD_CLOSE_DATABASE = "closeDatabase"; + static final public String METHOD_INSERT = "insert"; + static final public String METHOD_EXECUTE = "execute"; + static final public String METHOD_QUERY = "query"; + static final public String METHOD_QUERY_CURSOR_NEXT = "queryCursorNext"; + static final public String METHOD_UPDATE = "update"; + static final public String METHOD_BATCH = "batch"; + static final public String METHOD_DELETE_DATABASE = "deleteDatabase"; + static final public String METHOD_DATABASE_EXISTS = "databaseExists"; + // true when entering, false when leaving, null otherwise, should be named inTransactionChange instead + public static final String PARAM_IN_TRANSACTION_CHANGE = "inTransaction"; + // Set for calls within a transaction + public static final String PARAM_TRANSACTION_ID = "transactionId"; + // Special transaction id used for recovering a locked database. + public static final int TRANSACTION_ID_FORCE = -1; + // Result when opening a database + public static final String PARAM_RECOVERED = "recovered"; + // Result when opening a database + public static final String PARAM_RECOVERED_IN_TRANSACTION = "recoveredInTransaction"; + public static final String PARAM_SQL = "sql"; + public static final String PARAM_SQL_ARGUMENTS = "arguments"; + public static final String PARAM_NO_RESULT = "noResult"; + public static final String PARAM_CONTINUE_OR_ERROR = "continueOnError"; + public static final String PARAM_COLUMNS = "columns"; + public static final String PARAM_ROWS = "rows"; + // For query to use a cursor. Integer. + public static final String PARAM_CURSOR_PAGE_SIZE = "cursorPageSize"; + // For queryCursorNext. Integer + public static final String PARAM_CURSOR_ID = "cursorId"; + // For queryCursorNext. Boolean + public static final String PARAM_CANCEL = "cancel"; + // in each operation + public static final String PARAM_METHOD = "method"; + // Batch operation results + public static final String PARAM_RESULT = "result"; + public static final String PARAM_ERROR = "error"; // map with code/message/data + public static final String PARAM_ERROR_CODE = "code"; + public static final String PARAM_ERROR_MESSAGE = "message"; + public static final String PARAM_ERROR_DATA = "data"; + // android log tag + static final public String TAG = "Sqflite"; + // Obsolete since 1.17 + static final public String METHOD_DEBUG_MODE = "debugMode"; + static final public String METHOD_ANDROID_SET_LOCALE = "androidSetLocale"; + // Locale tag + static final String PARAM_LOCALE = "locale"; + public static final String[] EMPTY_STRING_ARRAY = new String[0]; + static final String PARAM_ID = "id"; + static final String PARAM_PATH = "path"; + // when opening a database + static final String PARAM_READ_ONLY = "readOnly"; // boolean + static final String PARAM_SINGLE_INSTANCE = "singleInstance"; // boolean + static final String PARAM_LOG_LEVEL = "logLevel"; // int + static final String PARAM_THREAD_PRIORITY = "androidThreadPriority"; // int + static final String PARAM_THREAD_COUNT = "androidThreadCount"; // int + + // debugMode + static final String PARAM_CMD = "cmd"; // debugMode cmd: get/set + static final String CMD_GET = "get"; + // in batch + static final String PARAM_OPERATIONS = "operations"; + static final String SQLITE_ERROR = "sqlite_error"; // code + static final String ERROR_BAD_PARAM = "bad_param"; // internal only + static final String ERROR_OPEN_FAILED = "open_failed"; // msg + static final String ERROR_DATABASE_CLOSED = "database_closed"; // msg + // memory database path + static final String MEMORY_DATABASE_PATH = ":memory:"; +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Database.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Database.java new file mode 100644 index 0000000000000000000000000000000000000000..bbea6926fc6636496459b8fcdbe279e9b58c3074 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Database.java @@ -0,0 +1,682 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static com.tekartik.sqflite.Constant.EMPTY_STRING_ARRAY; +import static com.tekartik.sqflite.Constant.ERROR_BAD_PARAM; +import static com.tekartik.sqflite.Constant.METHOD_EXECUTE; +import static com.tekartik.sqflite.Constant.METHOD_INSERT; +import static com.tekartik.sqflite.Constant.METHOD_QUERY; +import static com.tekartik.sqflite.Constant.METHOD_UPDATE; +import static com.tekartik.sqflite.Constant.PARAM_CANCEL; +import static com.tekartik.sqflite.Constant.PARAM_COLUMNS; +import static com.tekartik.sqflite.Constant.PARAM_CURSOR_ID; +import static com.tekartik.sqflite.Constant.PARAM_CURSOR_PAGE_SIZE; +import static com.tekartik.sqflite.Constant.PARAM_OPERATIONS; +import static com.tekartik.sqflite.Constant.PARAM_ROWS; +import static com.tekartik.sqflite.Constant.PARAM_TRANSACTION_ID; +import static com.tekartik.sqflite.Constant.TAG; +import static com.tekartik.sqflite.Constant.TRANSACTION_ID_FORCE; +import static com.tekartik.sqflite.Utils.cursorRowToList; + +import android.content.Context; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.database.DatabaseErrorHandler; +import android.database.SQLException; +import android.database.sqlite.SQLiteCantOpenDatabaseException; +import android.database.sqlite.SQLiteCursor; +import android.database.sqlite.SQLiteDatabase; +import android.os.Build; +import android.util.Log; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; + +import com.tekartik.sqflite.operation.BatchOperation; +import com.tekartik.sqflite.operation.MethodCallOperation; +import com.tekartik.sqflite.operation.Operation; +import com.tekartik.sqflite.operation.QueuedOperation; +import com.tekartik.sqflite.operation.SqlErrorInfo; + +import org.jetbrains.annotations.NotNull; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +class Database { + // To turn on when supported fully + // 2022-09-14 experiments show several corruption issue. + final static boolean WAL_ENABLED_BY_DEFAULT = false; + private static final String WAL_ENABLED_META_NAME = "com.tekartik.sqflite.wal_enabled"; + static private Boolean walGloballyEnabled; + final boolean singleInstance; + @NonNull + final String path; + final int id; + final int logLevel; + @NonNull + final Context context; + /// Delayed operations not in the current transaction. + final List noTransactionOperationQueue = new ArrayList<>(); + final Map cursors = new HashMap<>(); + // Set by plugin + public DatabaseWorkerPool databaseWorkerPool; + @Nullable + SQLiteDatabase sqliteDatabase; + private int transactionDepth = 0; + // Transaction + private int lastTransactionId = 0; // incremental transaction id + @Nullable + private Integer currentTransactionId; + // Cursors + private int lastCursorId = 0; // incremental cursor id + + Database(Context context, String path, int id, boolean singleInstance, int logLevel) { + this.context = context; + this.path = path; + this.singleInstance = singleInstance; + this.id = id; + this.logLevel = logLevel; + } + + @VisibleForTesting + @NotNull + static protected boolean checkWalEnabled(Context context) { + return checkMetaBoolean(context, WAL_ENABLED_META_NAME, WAL_ENABLED_BY_DEFAULT); + } + + @SuppressWarnings("deprecation") + static ApplicationInfo getApplicationInfoWithMeta32(Context context, String packageName, int flags) throws PackageManager.NameNotFoundException { + return context.getPackageManager().getApplicationInfo(packageName, flags); + } + + @VisibleForTesting + @NotNull + static protected boolean checkMetaBoolean(Context context, String metaKey, boolean defaultValue) { + try { + final String packageName = context.getPackageName(); + ApplicationInfo applicationInfo; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + applicationInfo = context.getPackageManager().getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(PackageManager.GET_META_DATA)); + } else { + applicationInfo = getApplicationInfoWithMeta32(context, packageName, PackageManager.GET_META_DATA); + } + final boolean walEnabled = applicationInfo.metaData.getBoolean(metaKey, defaultValue); + if (walEnabled) { + return true; + } + + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } + + + static void deleteDatabase(String path) { + SQLiteDatabase.deleteDatabase(new File(path)); + } + + /** + * Never fails + */ + public static boolean existsDatabase(String path) { + boolean exists = false; + try { + exists = new File(path).exists(); + } catch (Exception ignore) { + } + return exists; + } + + public void open() { + int flags = SQLiteDatabase.CREATE_IF_NECESSARY; + + // Check meta data only once + if (walGloballyEnabled == null) { + walGloballyEnabled = checkWalEnabled(context); + if (walGloballyEnabled) { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "[sqflite] WAL enabled"); + } + } + } + if (walGloballyEnabled) { + // Turned on since 2.1.0-dev.1 + flags |= SQLiteDatabase.ENABLE_WRITE_AHEAD_LOGGING; + } + + sqliteDatabase = SQLiteDatabase.openDatabase(path, null, flags); + } + + // Change default error handler to avoid erasing the existing file. + public void openReadOnly() { + sqliteDatabase = SQLiteDatabase.openDatabase(path, null, + SQLiteDatabase.OPEN_READONLY, new DatabaseErrorHandler() { + @Override + public void onCorruption(SQLiteDatabase dbObj) { + // ignored + // default implementation delete the file + // + // This happens asynchronously so cannot be tracked. However a simple + // access should fail + } + }); + } + + public void close() { + if (!cursors.isEmpty()) { + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + cursors.size() + " cursor(s) are left opened"); + } + } + sqliteDatabase.close(); + } + + public SQLiteDatabase getWritableDatabase() { + return sqliteDatabase; + } + + public SQLiteDatabase getReadableDatabase() { + return sqliteDatabase; + } + + public boolean enableWriteAheadLogging() { + try { + return sqliteDatabase.enableWriteAheadLogging(); + } catch (Exception e) { + Log.e(TAG, getThreadLogPrefix() + "enable WAL error: " + e); + return false; + } + } + + String getThreadLogTag() { + Thread thread = Thread.currentThread(); + + return "" + id + "," + thread.getName() + "(" + thread.getId() + ")"; + } + + String getThreadLogPrefix() { + return "[" + getThreadLogTag() + "] "; + } + + private Map cursorToResults(Cursor cursor, @Nullable Integer cursorPageSize) { + Map results = null; + List> rows = null; + int columnCount = 0; + while (cursor.moveToNext()) { + + if (results == null) { + rows = new ArrayList<>(); + results = new HashMap<>(); + columnCount = cursor.getColumnCount(); + results.put(PARAM_COLUMNS, Arrays.asList(cursor.getColumnNames())); + results.put(PARAM_ROWS, rows); + } + rows.add(cursorRowToList(cursor, columnCount)); + + // Paging support + if (cursorPageSize != null) { + if (rows.size() >= cursorPageSize) { + break; + } + } + } + // Handle empty + if (results == null) { + results = new HashMap<>(); + } + + return results; + } + + private void runQueuedOperations() { + while (!noTransactionOperationQueue.isEmpty()) { + if (currentTransactionId != null) { + break; + } + QueuedOperation queuedOperation = noTransactionOperationQueue.get(0); + queuedOperation.run(); + noTransactionOperationQueue.remove(0); + } + } + + private void wrapSqlOperationHandler(final @NonNull Operation operation, Runnable r) { + Integer transactionId = operation.getTransactionId(); + if (currentTransactionId == null) { + // ignore transactionId, could be null or -1 or something else if closed... + r.run(); + } else if (transactionId != null && (transactionId.equals(currentTransactionId) || transactionId == TRANSACTION_ID_FORCE)) { + r.run(); + // run queued action asynchronously + if (currentTransactionId == null && !noTransactionOperationQueue.isEmpty()) { + databaseWorkerPool.post(this, this::runQueuedOperations); + } + + } else { + // Queue for later + QueuedOperation queuedOperation = new QueuedOperation(operation, r); + noTransactionOperationQueue.add(queuedOperation); + } + } + + public void query(final @NonNull Operation operation) { + wrapSqlOperationHandler(operation, () -> doQuery(operation)); + } + + private boolean doQuery(final @NonNull Operation operation) { + // Non null means dealing with saved cursor. + Integer cursorPageSize = operation.getArgument(PARAM_CURSOR_PAGE_SIZE); + boolean cursorHasMoreData = false; + + final SqlCommand command = operation.getSqlCommand(); + + + // Might be created if reading by page and result don't fit + SqfliteCursor sqfliteCursor = null; + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + command); + } + Cursor cursor = null; + + try { + cursor = getReadableDatabase().rawQueryWithFactory( + (sqLiteDatabase, sqLiteCursorDriver, editTable, sqLiteQuery) -> { + command.bindTo(sqLiteQuery); + return new SQLiteCursor(sqLiteCursorDriver, editTable, sqLiteQuery); + }, command.getSql(), EMPTY_STRING_ARRAY, null); + + Map results = cursorToResults(cursor, cursorPageSize); + if (cursorPageSize != null) { + // We'll have potentially more data to fetch + cursorHasMoreData = !(cursor.isLast() || cursor.isAfterLast()); + + } + + if (cursorHasMoreData) { + int cursorId = ++lastCursorId; + results.put(PARAM_CURSOR_ID, cursorId); + sqfliteCursor = new SqfliteCursor(cursorId, cursorPageSize, cursor); + cursors.put(cursorId, sqfliteCursor); + } + operation.success(results); + + return true; + + } catch (Exception exception) { + handleException(exception, operation); + // Cleanup + if (sqfliteCursor != null) { + closeCursor(sqfliteCursor); + } + return false; + } finally { + // Close the cursor for non-paged query + if (sqfliteCursor == null) { + if (cursor != null) { + cursor.close(); + } + } + } + } + + public void queryCursorNext(final @NonNull Operation operation) { + wrapSqlOperationHandler(operation, () -> doQueryCursorNext(operation)); + } + + private boolean doQueryCursorNext(final @NonNull Operation operation) { + // Non null means dealing with saved cursor. + int cursorId = operation.getArgument(PARAM_CURSOR_ID); + boolean cancel = Boolean.TRUE.equals(operation.getArgument(PARAM_CANCEL)); + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "cursor " + cursorId + (cancel ? " cancel" : " next")); + } + if (cancel) { + closeCursor(cursorId); + operation.success(null); + return true; + } + SqfliteCursor sqfliteCursor = cursors.get(cursorId); + boolean cursorHasMoreData = false; + try { + if (sqfliteCursor == null) { + throw new IllegalStateException("Cursor " + cursorId + " not found"); + } + Cursor cursor = sqfliteCursor.cursor; + + Map results = cursorToResults(cursor, sqfliteCursor.pageSize); + + // We'll have potentially more data to fetch + cursorHasMoreData = !(cursor.isLast() || cursor.isAfterLast()); + + if (cursorHasMoreData) { + // Keep the cursor Id in the response to specify that we have more data + results.put(PARAM_CURSOR_ID, cursorId); + } + operation.success(results); + + return true; + + } catch (Exception exception) { + handleException(exception, operation); + // Cleanup + if (sqfliteCursor != null) { + closeCursor(sqfliteCursor); + sqfliteCursor = null; + } + return false; + } finally { + // Close the cursor if we don't have any more data + if (!cursorHasMoreData) { + if (sqfliteCursor != null) { + closeCursor(sqfliteCursor); + } + } + } + } + + private void closeCursor(@NonNull SqfliteCursor sqfliteCursor) { + try { + int cursorId = sqfliteCursor.cursorId; + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "closing cursor " + cursorId); + } + cursors.remove(cursorId); + sqfliteCursor.cursor.close(); + } catch (Exception ignore) { + } + } + + // No exception thrown here + private void closeCursor(int cursorId) { + SqfliteCursor sqfliteCursor = cursors.get(cursorId); + if (sqfliteCursor != null) { + closeCursor(sqfliteCursor); + } + } + + void handleException(Exception exception, Operation operation) { + if (exception instanceof SQLiteCantOpenDatabaseException) { + operation.error(Constant.SQLITE_ERROR, Constant.ERROR_OPEN_FAILED + " " + path, null); + return; + } else if (exception instanceof SQLException) { + operation.error(Constant.SQLITE_ERROR, exception.getMessage(), SqlErrorInfo.getMap(operation)); + return; + } + operation.error(Constant.SQLITE_ERROR, exception.getMessage(), SqlErrorInfo.getMap(operation)); + } + + // Called during batch, warning duplicated code! + private boolean executeOrError(Operation operation) { + SqlCommand command = operation.getSqlCommand(); + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + command); + } + Boolean operationInTransaction = operation.getInTransactionChange(); + try { + getWritableDatabase().execSQL(command.getSql(), command.getSqlArguments()); + enterOrLeaveInTransaction(operationInTransaction); + return true; + } catch (Exception exception) { + handleException(exception, operation); + return false; + } + } + + /** + * Handle inTransactionChange + * + * @param operation + * @return + */ + public void execute(final @NonNull Operation operation) { + wrapSqlOperationHandler(operation, () -> { + Boolean inTransactionChange = operation.getInTransactionChange(); + // Transaction v2 support + boolean enteringTransaction = Boolean.TRUE.equals(inTransactionChange) && operation.hasNullTransactionId(); + if (enteringTransaction) { + currentTransactionId = ++lastTransactionId; + } + if (!executeOrError(operation)) { + // Revert if needed + if (enteringTransaction) { + currentTransactionId = null; + } + + } else if (enteringTransaction) { + /// Return the transaction id + Map result = new HashMap<>(); + result.put(PARAM_TRANSACTION_ID, currentTransactionId); + operation.success(result); + } else { + if (Boolean.FALSE.equals(inTransactionChange)) { + // We are leaving our current transaction + currentTransactionId = null; + } + operation.success(null); + } + }); + } + + // Return true on success + private boolean doExecute(final Operation operation) { + if (!executeOrError(operation)) { + return false; + } + operation.success(null); + return true; + } + + public void insert(final Operation operation) { + wrapSqlOperationHandler(operation, () -> doInsert(operation)); + } + + // Return true on success + private boolean doInsert(final Operation operation) { + if (!executeOrError(operation)) { + return false; + } + // don't get last id if not expected + if (operation.getNoResult()) { + operation.success(null); + return true; + } + + Cursor cursor = null; + // Read both the changes and last insert row id in on sql call + String sql = "SELECT changes(), last_insert_rowid()"; + + // Handle ON CONFLICT but ignore error, issue #164 + // Read the number of changes before getting the inserted id + try { + SQLiteDatabase db = getWritableDatabase(); + + cursor = db.rawQuery(sql, null); + if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) { + final int changed = cursor.getInt(0); + + // If the change count is 0, assume the insert failed + // and return null + if (changed == 0) { + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "no changes (id was " + cursor.getLong(1) + ")"); + } + operation.success(null); + return true; + } else { + final long id = cursor.getLong(1); + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "inserted " + id); + } + operation.success(id); + return true; + } + } else { + Log.e(TAG, getThreadLogPrefix() + "fail to read changes for Insert"); + } + operation.success(null); + return true; + } catch (Exception exception) { + handleException(exception, operation); + return false; + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + + public void update(final @NonNull Operation operation) { + wrapSqlOperationHandler(operation, () -> doUpdate(operation)); + } + + // Return true on success + private boolean doUpdate(final Operation operation) { + if (!executeOrError(operation)) { + return false; + } + // don't get last id if not expected + if (operation.getNoResult()) { + operation.success(null); + return true; + } + Cursor cursor = null; + try { + SQLiteDatabase db = getWritableDatabase(); + + cursor = db.rawQuery("SELECT changes()", null); + if (cursor != null && cursor.getCount() > 0 && cursor.moveToFirst()) { + final int changed = cursor.getInt(0); + if (LogLevel.hasSqlLevel(logLevel)) { + Log.d(TAG, getThreadLogPrefix() + "changed " + changed); + } + operation.success(changed); + return true; + } else { + Log.e(TAG, getThreadLogPrefix() + "fail to read changes for Update/Delete"); + } + operation.success(null); + return true; + } catch (Exception e) { + handleException(e, operation); + return false; + } finally { + if (cursor != null) { + cursor.close(); + } + } + } + + void batch(final MethodCall call, final MethodChannel.Result result) { + MethodCallOperation mainOperation = new MethodCallOperation(call, result); + + boolean noResult = mainOperation.getNoResult(); + boolean continueOnError = mainOperation.getContinueOnError(); + + List> operations = mainOperation.getArgument(PARAM_OPERATIONS); + List> results = new ArrayList<>(); + + //devLog(TAG, "operations " + operations); + for (Map map : operations) { + //devLog(TAG, "map " + map); + BatchOperation operation = new BatchOperation(map, noResult); + String method = operation.getMethod(); + switch (method) { + case METHOD_EXECUTE: + if (doExecute(operation)) { + //devLog(TAG, "results: " + operation.getBatchResults()); + operation.handleSuccess(results); + } else if (continueOnError) { + operation.handleErrorContinue(results); + } else { + // we stop at the first error + operation.handleError(result); + return; + } + break; + case METHOD_INSERT: + if (doInsert(operation)) { + //devLog(TAG, "results: " + operation.getBatchResults()); + operation.handleSuccess(results); + } else if (continueOnError) { + operation.handleErrorContinue(results); + } else { + // we stop at the first error + operation.handleError(result); + return; + } + break; + case METHOD_QUERY: + if (doQuery(operation)) { + //devLog(TAG, "results: " + operation.getBatchResults()); + operation.handleSuccess(results); + } else if (continueOnError) { + operation.handleErrorContinue(results); + } else { + // we stop at the first error + operation.handleError(result); + return; + } + break; + case METHOD_UPDATE: + if (doUpdate(operation)) { + //devLog(TAG, "results: " + operation.getBatchResults()); + operation.handleSuccess(results); + } else if (continueOnError) { + operation.handleErrorContinue(results); + } else { + // we stop at the first error + operation.handleError(result); + return; + } + break; + default: + result.error(ERROR_BAD_PARAM, "Batch method '" + method + "' not supported", null); + return; + } + } + // Set the results of all operations + // devLog(TAG, "results " + results); + if (noResult) { + result.success(null); + } else { + result.success(results); + } + } + + synchronized boolean isInTransaction() { + return transactionDepth > 0; + } + + synchronized void enterOrLeaveInTransaction(Boolean value) { + if (Boolean.TRUE.equals(value)) { + transactionDepth++; + } else if (Boolean.FALSE.equals(value)) { + transactionDepth--; + } + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseTask.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseTask.java new file mode 100644 index 0000000000000000000000000000000000000000..cf0bca2e62c4b822967f183a9f9f7453bb49a5c4 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseTask.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import androidx.annotation.Nullable; + +interface DatabaseDelegate { + int getDatabaseId(); + boolean isInTransaction(); +} + +final class DatabaseTask { + + // Database this task will be run on. + // + // It can be null if the task is not running on any database. e.g. closing a NULL database. + @Nullable + private final DatabaseDelegate database; + final Runnable runnable; + + DatabaseTask(DatabaseDelegate database, Runnable runnable) { + this.database = database; + this.runnable = runnable; + } + + public boolean isInTransaction() { + return database != null && database.isInTransaction(); + } + + public Integer getDatabaseId() { + return database != null ? database.getDatabaseId() : null; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorker.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorker.java new file mode 100644 index 0000000000000000000000000000000000000000..6e14d2c2724ea0ad2bbd7d599800e2f8c7667ed3 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorker.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import android.os.Handler; +import android.os.HandlerThread; + +/** + * Worker that accepts {@link DatabaseTask}. + * + *

Each worker instance run on one thread. + */ +class DatabaseWorker { + + private final String name; + private final int priority; + + private HandlerThread handlerThread; + private Handler handler; + protected Runnable onIdle; + + private DatabaseTask lastTask; + + DatabaseWorker(String name, int priority) { + this.name = name; + this.priority = priority; + } + + synchronized void start(Runnable onIdle) { + handlerThread = new HandlerThread(name, priority); + handlerThread.start(); + handler = new Handler(handlerThread.getLooper()); + this.onIdle = onIdle; + } + + synchronized void quit() { + if (handlerThread != null) { + handlerThread.quit(); + handlerThread = null; + handler = null; + } + } + + boolean isLastTaskInTransaction() { + return lastTask != null && lastTask.isInTransaction(); + } + + Integer lastTaskDatabaseId() { + return lastTask != null ? lastTask.getDatabaseId() : null; + } + + void postTask(final DatabaseTask task) { + handler.post(() -> this.work(task)); + } + + void work(DatabaseTask task) { + task.runnable.run(); + lastTask = task; + onIdle.run(); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorkerPool.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorkerPool.java new file mode 100644 index 0000000000000000000000000000000000000000..72e45f6b32c42a086a91f89ae5f8dc34a105f582 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/DatabaseWorkerPool.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import android.os.Handler; +import android.os.HandlerThread; + +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.ListIterator; +import java.util.Map; +import java.util.Set; + +/** + * Pool that assigns {@link DatabaseTask} to {@link DatabaseWorker}. + */ +public interface DatabaseWorkerPool { + void start(); + + void quit(); + + // Posts a new task. + // + // Some rules for assigning a task to a worker. + // - All tasks in a transaction go to the same worker. Otherwise errors will happen. + // - All tasks belonging to the same database run in FIFO manner. No overlapping between any + // two tasks. + // - Tasks belonging to different databases could be run simultaneously but not necessarily + // in FIFO manner. + void post(DatabaseTask task); + + default void post(Database database, Runnable runnable) { + DatabaseDelegate delegate = database == null ? null : new DatabaseDelegate() { + @Override + public int getDatabaseId() { + return database.id; + } + + @Override + public boolean isInTransaction() { + return database.isInTransaction(); + } + }; + this.post(new DatabaseTask(delegate, runnable)); + } + + static DatabaseWorkerPool create(String name, int numberOfWorkers, int priority) { + if (numberOfWorkers == 1) { + return new SingleDatabaseWorkerPoolImpl(name, priority); + } + return new DatabaseWorkerPoolImpl(name, numberOfWorkers, priority); + } +} + +class SingleDatabaseWorkerPoolImpl implements DatabaseWorkerPool { + + final String name; + final int priority; + + private HandlerThread handlerThread; + private Handler handler; + + SingleDatabaseWorkerPoolImpl(String name, int priority) { + this.name = name; + this.priority = priority; + } + + @Override + public void start() { + handlerThread = new HandlerThread(name, priority); + handlerThread.start(); + handler = new Handler(handlerThread.getLooper()); + } + + @Override + public void quit() { + if (handlerThread != null) { + handlerThread.quit(); + handlerThread = null; + handler = null; + } + } + + @Override + public void post(DatabaseTask task) { + handler.post(task.runnable); + } +} + +class DatabaseWorkerPoolImpl implements DatabaseWorkerPool { + + final String name; + final int numberOfWorkers; + final int priority; + + private final LinkedList waitingList = new LinkedList<>(); + private final Set idleWorkers = new HashSet<>(); + private final Set busyWorkers = new HashSet<>(); + + // A map from database id to the only eligible worker. + // + // When a database id is found in the map, tasks of the database should only be run by the + // corresponding worker. Otherwise, any worker is eligible. + private final Map onlyEligibleWorkers = new HashMap<>(); + + DatabaseWorkerPoolImpl(String name, int numberOfWorkers, int priority) { + this.name = name; + this.numberOfWorkers = numberOfWorkers; + this.priority = priority; + } + + @Override + public synchronized void start() { + for (int i = 0; i < numberOfWorkers; i++) { + DatabaseWorker worker = createWorker(name + i, priority); + worker.start( + () -> { + onWorkerIdle(worker); + }); + idleWorkers.add(worker); + } + } + + protected DatabaseWorker createWorker(String name, int priority) { + return new DatabaseWorker(name, priority); + } + + @Override + public synchronized void quit() { + for (DatabaseWorker worker : idleWorkers) { + worker.quit(); + } + for (DatabaseWorker worker : busyWorkers) { + worker.quit(); + } + } + + @Override + public synchronized void post(DatabaseTask task) { + waitingList.add(task); + + Set workers = new HashSet<>(idleWorkers); + for (DatabaseWorker worker : workers) { + tryPostingTaskToWorker(worker); + } + } + + private synchronized void tryPostingTaskToWorker(DatabaseWorker worker) { + DatabaseTask task = findTaskForWorker(worker); + if (task != null) { + // Mark the worker busy. + busyWorkers.add(worker); + idleWorkers.remove(worker); + + // Since now, the worker is the only eligible one to work on the corresponding database. + // Allowing others to work on the same database could break the "FIFO manner". + if (task.getDatabaseId() != null) { + onlyEligibleWorkers.put(task.getDatabaseId(), worker); + } + worker.postTask(task); + } + } + + private synchronized DatabaseTask findTaskForWorker(DatabaseWorker worker) { + ListIterator iter = waitingList.listIterator(); + while (iter.hasNext()) { + DatabaseTask task = iter.next(); + DatabaseWorker onlyEligibleWorker = null; + if (task.getDatabaseId() != null) { + onlyEligibleWorker = onlyEligibleWorkers.get(task.getDatabaseId()); + } + // Skip current task when the worker is not eligible for it. + if (onlyEligibleWorker != null && onlyEligibleWorker != worker) { + continue; + } else { + iter.remove(); + return task; + } + } + return null; + } + + private synchronized void onWorkerIdle(DatabaseWorker worker) { + // Clone idleWorkers before it get modified. + Set others = new HashSet<>(idleWorkers); + + // Mark the worker idle. + busyWorkers.remove(worker); + idleWorkers.add(worker); + + // The last task was done and any other worker is eligible to work on the corresponding + // database since then. However, there is one exception that the last task is in + // transaction and current worker is still the only eligible one. + if (!worker.isLastTaskInTransaction() && worker.lastTaskDatabaseId() != null) { + onlyEligibleWorkers.remove(worker.lastTaskDatabaseId()); + } + tryPostingTaskToWorker(worker); + + // The eligible relationship was changed above. Try posting tasks again. + for (DatabaseWorker other : others) { + tryPostingTaskToWorker(other); + } + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LocaleUtils.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LocaleUtils.java new file mode 100644 index 0000000000000000000000000000000000000000..69511e9add3dfe4210909c27c878fcff4af17f60 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LocaleUtils.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import android.os.Build; + +import androidx.annotation.RequiresApi; + +import java.util.Locale; + +public class LocaleUtils { + + + static Locale localeForLanguateTag(String localeString) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return localeForLanguageTag21(localeString); + } else { + return localeForLanguageTagPre21(localeString); + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + static Locale localeForLanguageTag21(String localeString) { + return Locale.forLanguageTag(localeString); + } + + /** + * Really basic implementation, hopefully not so many dev/apps with such requirements + * should be impacted. + * + * @param localeString + * @return + */ + static Locale localeForLanguageTagPre21(String localeString) { + //Locale.Builder builder = new Locale().Builder(); + String[] parts = localeString.split("-"); + String language = ""; + String country = ""; + String variant = ""; + if (parts.length > 0) { + language = parts[0]; + if (parts.length > 1) { + country = parts[1]; + + if (parts.length > 2) { + variant = parts[parts.length - 1]; + } + } + } + return new Locale(language, country, variant); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LogLevel.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LogLevel.java new file mode 100644 index 0000000000000000000000000000000000000000..ec8ffd5030d6dee04aec44c25d997811b1c007ca --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/LogLevel.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static com.tekartik.sqflite.Constant.PARAM_LOG_LEVEL; + +import io.flutter.plugin.common.MethodCall; + +public class LogLevel { + + static final int none = 0; + static final int sql = 1; + static final int verbose = 2; + + static Integer getLogLevel(MethodCall methodCall) { + return methodCall.argument(PARAM_LOG_LEVEL); + } + + static boolean hasSqlLevel(int level) { + return level >= sql; + } + + static boolean hasVerboseLevel(int level) { + return level >= verbose; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqfliteCursor.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqfliteCursor.java new file mode 100644 index 0000000000000000000000000000000000000000..7aebcec8b3775e236ff44261119230b9b3ed362a --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqfliteCursor.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import android.database.Cursor; + +/** + * Sqflite cursor + */ +public class SqfliteCursor { + final int cursorId; + final int pageSize; + final Cursor cursor; + + public SqfliteCursor(int cursorId, int pageSize, Cursor cursor) { + this.cursorId = cursorId; + this.pageSize = pageSize; + this.cursor = cursor; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqflitePlugin.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqflitePlugin.java new file mode 100644 index 0000000000000000000000000000000000000000..e7f1ed1bf46dccac8d8d3a5072ccac28b8709a24 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqflitePlugin.java @@ -0,0 +1,706 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static com.tekartik.sqflite.Constant.CMD_GET; +import static com.tekartik.sqflite.Constant.MEMORY_DATABASE_PATH; +import static com.tekartik.sqflite.Constant.METHOD_ANDROID_SET_LOCALE; +import static com.tekartik.sqflite.Constant.METHOD_BATCH; +import static com.tekartik.sqflite.Constant.METHOD_CLOSE_DATABASE; +import static com.tekartik.sqflite.Constant.METHOD_DATABASE_EXISTS; +import static com.tekartik.sqflite.Constant.METHOD_DEBUG; +import static com.tekartik.sqflite.Constant.METHOD_DEBUG_MODE; +import static com.tekartik.sqflite.Constant.METHOD_DELETE_DATABASE; +import static com.tekartik.sqflite.Constant.METHOD_EXECUTE; +import static com.tekartik.sqflite.Constant.METHOD_GET_DATABASES_PATH; +import static com.tekartik.sqflite.Constant.METHOD_GET_PLATFORM_VERSION; +import static com.tekartik.sqflite.Constant.METHOD_INSERT; +import static com.tekartik.sqflite.Constant.METHOD_OPEN_DATABASE; +import static com.tekartik.sqflite.Constant.METHOD_OPTIONS; +import static com.tekartik.sqflite.Constant.METHOD_QUERY; +import static com.tekartik.sqflite.Constant.METHOD_QUERY_CURSOR_NEXT; +import static com.tekartik.sqflite.Constant.METHOD_UPDATE; +import static com.tekartik.sqflite.Constant.PARAM_CMD; +import static com.tekartik.sqflite.Constant.PARAM_ID; +import static com.tekartik.sqflite.Constant.PARAM_LOCALE; +import static com.tekartik.sqflite.Constant.PARAM_LOG_LEVEL; +import static com.tekartik.sqflite.Constant.PARAM_PATH; +import static com.tekartik.sqflite.Constant.PARAM_READ_ONLY; +import static com.tekartik.sqflite.Constant.PARAM_RECOVERED; +import static com.tekartik.sqflite.Constant.PARAM_RECOVERED_IN_TRANSACTION; +import static com.tekartik.sqflite.Constant.PARAM_SINGLE_INSTANCE; +import static com.tekartik.sqflite.Constant.TAG; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Process; +import android.util.Log; + +import com.tekartik.sqflite.dev.Debug; +import com.tekartik.sqflite.operation.MethodCallOperation; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.embedding.engine.plugins.FlutterPlugin; +import io.flutter.plugin.common.BinaryMessenger; +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; +import io.flutter.plugin.common.MethodChannel.MethodCallHandler; +import io.flutter.plugin.common.MethodChannel.Result; +import io.flutter.plugin.common.StandardMethodCodec; + +/** + * SqflitePlugin Android implementation + */ +public class SqflitePlugin implements FlutterPlugin, MethodCallHandler { + + static final Map _singleInstancesByPath = new HashMap<>(); + @SuppressLint("UseSparseArrays") + static final Map databaseMap = new HashMap<>(); + static private final Object databaseMapLocker = new Object(); + static private final Object openCloseLocker = new Object(); + static int logLevel = LogLevel.none; + // local cache + static String databasesPath; + static private int THREAD_PRIORITY = Process.THREAD_PRIORITY_DEFAULT; + static private int THREAD_COUNT = 1; + static private int databaseId = 0; // incremental database id + // Database worker pool execution + static private DatabaseWorkerPool databaseWorkerPool; + private Context context; + private MethodChannel methodChannel; + + // Needed public constructor + public SqflitePlugin() { + + } + + // Testing only + public SqflitePlugin(Context context) { + this.context = context.getApplicationContext(); + } + + // + // Plugin registration. + // + @SuppressWarnings("deprecation") + public static void registerWith(io.flutter.plugin.common.PluginRegistry.Registrar registrar) { + SqflitePlugin sqflitePlugin = new SqflitePlugin(); + sqflitePlugin.onAttachedToEngine(registrar.context(), registrar.messenger()); + } + + static private Map fixMap(Map map) { + Map newMap = new HashMap<>(); + for (Map.Entry entry : map.entrySet()) { + Object value = entry.getValue(); + if (value instanceof Map) { + @SuppressWarnings("unchecked") + Map mapValue = (Map) value; + value = fixMap(mapValue); + } else { + value = toString(value); + } + newMap.put(toString(entry.getKey()), value); + } + return newMap; + } + + // Convert a value to a string + // especially byte[] + static private String toString(Object value) { + if (value == null) { + return null; + } else if (value instanceof byte[]) { + List list = new ArrayList<>(); + for (byte _byte : (byte[]) value) { + list.add((int) _byte); + } + return list.toString(); + } else if (value instanceof Map) { + @SuppressWarnings("unchecked") + Map mapValue = (Map) value; + return fixMap(mapValue).toString(); + } else { + return value.toString(); + } + } + + static boolean isInMemoryPath(String path) { + return (path == null || path.equals(MEMORY_DATABASE_PATH)); + } + + // { + // 'id': xxx + // 'recovered': true // if recovered only for single instance + // } + static Map makeOpenResult(int databaseId, boolean recovered, boolean recoveredInTransaction) { + Map result = new HashMap<>(); + result.put(PARAM_ID, databaseId); + if (recovered) { + result.put(PARAM_RECOVERED, true); + } + if (recoveredInTransaction) { + result.put(PARAM_RECOVERED_IN_TRANSACTION, true); + } + return result; + } + + @Override + public void onAttachedToEngine(FlutterPluginBinding binding) { + onAttachedToEngine(binding.getApplicationContext(), binding.getBinaryMessenger()); + } + + private void onAttachedToEngine(Context applicationContext, BinaryMessenger messenger) { + this.context = applicationContext; + methodChannel = new MethodChannel(messenger, Constant.PLUGIN_KEY, + StandardMethodCodec.INSTANCE, + messenger.makeBackgroundTaskQueue()); + methodChannel.setMethodCallHandler(this); + } + + @Override + public void onDetachedFromEngine(FlutterPluginBinding binding) { + context = null; + methodChannel.setMethodCallHandler(null); + methodChannel = null; + } + + private Context getContext() { + return context; + } + + private Database getDatabase(int databaseId) { + return databaseMap.get(databaseId); + } + + private Database getDatabaseOrError(MethodCall call, Result result) { + int databaseId = call.argument(PARAM_ID); + Database database = getDatabase(databaseId); + + if (database != null) { + return database; + } else { + result.error(Constant.SQLITE_ERROR, Constant.ERROR_DATABASE_CLOSED + " " + databaseId, null); + return null; + } + } + + // + // query + // + private void onQueryCall(final MethodCall call, final Result result) { + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.query(operation); + }); + } + + // + // cursor query next + // + private void onQueryCursorNextCall(final MethodCall call, final Result result) { + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.queryCursorNext(operation); + }); + } + + // + // Sqflite.batch + // + private void onBatchCall(final MethodCall call, final Result result) { + + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> database.batch(call, result)); + } + + // + // Insert + // + private void onInsertCall(final MethodCall call, final Result result) { + + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.insert(operation); + }); + } + + // + // Sqflite.execute + // + private void onExecuteCall(final MethodCall call, final Result result) { + + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.execute(operation); + }); + } + + private void onSetLocaleCall(final MethodCall call, final Result result) { + + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + String localeString = call.argument(PARAM_LOCALE); + try { + database.sqliteDatabase.setLocale(Utils.localeForLanguateTag(localeString)); + result.success(null); + } catch (Exception exception) { + result.error(Constant.SQLITE_ERROR, "Error calling setLocale: " + exception.getMessage(), null); + } + + }); + } + + // + // Sqflite.update + // + private void onUpdateCall(final MethodCall call, final Result result) { + + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + databaseWorkerPool.post(database, () -> { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.update(operation); + }); + } + + private void onDebugCall(final MethodCall call, final Result result) { + String cmd = call.argument(PARAM_CMD); + Map map = new HashMap<>(); + + // Get database info + + if (CMD_GET.equals(cmd)) { + if (logLevel > LogLevel.none) { + map.put(PARAM_LOG_LEVEL, logLevel); + } + if (!databaseMap.isEmpty()) { + Map databasesInfo = new HashMap<>(); + for (Map.Entry entry : databaseMap.entrySet()) { + Database database = entry.getValue(); + Map info = new HashMap<>(); + info.put(PARAM_PATH, database.path); + info.put(PARAM_SINGLE_INSTANCE, database.singleInstance); + if (database.logLevel > LogLevel.none) { + info.put(PARAM_LOG_LEVEL, database.logLevel); + } + databasesInfo.put(entry.getKey().toString(), info); + + } + map.put("databases", databasesInfo); + } + } + result.success(map); + } + + + // Deprecated since 1.1.6 + private void onDebugModeCall(final MethodCall call, final Result result) { + // Old / argument was just a boolean + Object on = call.arguments(); + Debug.LOGV = Boolean.TRUE.equals(on); + Debug.EXTRA_LOGV = Debug._EXTRA_LOGV && Debug.LOGV; + + // set default logs to match existing + if (Debug.LOGV) { + if (Debug.EXTRA_LOGV) { + logLevel = LogLevel.verbose; + } else if (Debug.LOGV) { + logLevel = LogLevel.sql; + } + + } else { + logLevel = LogLevel.none; + } + result.success(null); + } + + // + // Sqflite.open + // + private void onOpenDatabaseCall(final MethodCall call, final Result result) { + final String path = call.argument(PARAM_PATH); + final Boolean readOnly = call.argument(PARAM_READ_ONLY); + final boolean inMemory = isInMemoryPath(path); + + final boolean singleInstance = !Boolean.FALSE.equals(call.argument(PARAM_SINGLE_INSTANCE)) && !inMemory; + + // For single instance we create or reuse a thread right away + // DO NOT TRY TO LOAD existing instance, the database has been closed + + + if (singleInstance) { + // Look for in memory instance + synchronized (databaseMapLocker) { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, "Look for " + path + " in " + _singleInstancesByPath.keySet()); + } + Integer databaseId = _singleInstancesByPath.get(path); + if (databaseId != null) { + Database database = databaseMap.get(databaseId); + if (database != null) { + if (!database.sqliteDatabase.isOpen()) { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, database.getThreadLogPrefix() + "single instance database of " + path + " not opened"); + } + } else { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, database.getThreadLogPrefix() + "re-opened single instance " + (database.isInTransaction() ? "(in transaction) " : "") + databaseId + " " + path); + } + result.success(makeOpenResult(databaseId, true, database.isInTransaction())); + return; + } + } + } + } + } + + // Generate new id + int newDatabaseId; + synchronized (databaseMapLocker) { + newDatabaseId = ++databaseId; + } + final int databaseId = newDatabaseId; + + final Database database = new Database(context, path, databaseId, singleInstance, logLevel); + + synchronized (databaseMapLocker) { + // Create worker pool if necessary + if (databaseWorkerPool == null) { + databaseWorkerPool = DatabaseWorkerPool.create( + "Sqflite", THREAD_COUNT, SqflitePlugin.THREAD_PRIORITY); + databaseWorkerPool.start(); + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "starting worker pool with priority " + SqflitePlugin.THREAD_PRIORITY); + } + } + database.databaseWorkerPool = databaseWorkerPool; + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "opened " + databaseId + " " + path); + } + + + // Open in background thread + databaseWorkerPool.post( + database, + () -> { + + synchronized (openCloseLocker) { + + if (!inMemory) { + File file = new File(path); + File directory = new File(file.getParent()); + if (!directory.exists()) { + if (!directory.mkdirs()) { + if (!directory.exists()) { + result.error(Constant.SQLITE_ERROR, Constant.ERROR_OPEN_FAILED + " " + path, null); + return; + } + } + } + } + + // force opening + try { + if (Boolean.TRUE.equals(readOnly)) { + database.openReadOnly(); + } else { + database.open(); + } + } catch (Exception e) { + MethodCallOperation operation = new MethodCallOperation(call, result); + database.handleException(e, operation); + return; + } + + synchronized (databaseMapLocker) { + if (singleInstance) { + _singleInstancesByPath.put(path, databaseId); + } + databaseMap.put(databaseId, database); + } + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "opened " + databaseId + " " + path); + } + } + + result.success(makeOpenResult(databaseId, false, false)); + }); + } + + } + + // + // Sqflite.close + // + private void onCloseDatabaseCall(MethodCall call, final Result result) { + final int databaseId = call.argument(PARAM_ID); + final Database database = getDatabaseOrError(call, result); + if (database == null) { + return; + } + + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "closing " + databaseId + " " + database.path); + } + + final String path = database.path; + + // Remove from map right away + synchronized (databaseMapLocker) { + databaseMap.remove(databaseId); + + if (database.singleInstance) { + _singleInstancesByPath.remove(path); + } + } + + databaseWorkerPool.post(database, new Runnable() { + @Override + public void run() { + synchronized (openCloseLocker) { + closeDatabase(database); + } + + result.success(null); + } + }); + + } + + // + // Sqflite.open + // + private void onDeleteDatabaseCall(final MethodCall call, final Result result) { + final String path = call.argument(PARAM_PATH); + Database foundOpenedDatabase = null; + // Look for in memory instance + synchronized (databaseMapLocker) { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, "Look for " + path + " in " + _singleInstancesByPath.keySet()); + } + Integer databaseId = _singleInstancesByPath.get(path); + if (databaseId != null) { + Database database = databaseMap.get(databaseId); + if (database != null) { + if (database.sqliteDatabase.isOpen()) { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, database.getThreadLogPrefix() + "found single instance " + (database.isInTransaction() ? "(in transaction) " : "") + databaseId + " " + path); + } + foundOpenedDatabase = database; + + // Remove from map right away + databaseMap.remove(databaseId); + _singleInstancesByPath.remove(path); + } + } + } + } + final Database openedDatabase = foundOpenedDatabase; + + final Runnable deleteRunnable = new Runnable() { + @Override + public void run() { + synchronized (openCloseLocker) { + + if (openedDatabase != null) { + closeDatabase(openedDatabase); + } + try { + if (LogLevel.hasVerboseLevel(logLevel)) { + Log.d(Constant.TAG, "delete database " + path); + } + Database.deleteDatabase(path); + } catch (Exception e) { + Log.e(TAG, "error " + e + " while closing database " + databaseId); + } + } + result.success(null); + } + }; + + // worker pool might not exist yet + if (databaseWorkerPool != null) { + databaseWorkerPool.post(openedDatabase, deleteRunnable); + } else { + // Otherwise run in the UI thread + deleteRunnable.run(); + } + + } + + private void onDatabaseExistsCall(final MethodCall call, final Result result) { + final String path = call.argument(PARAM_PATH); + boolean exists = Database.existsDatabase(path); + result.success(exists); + } + + private void closeDatabase(Database database) { + try { + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "closing database "); + } + database.close(); + } catch (Exception e) { + Log.e(TAG, "error " + e + " while closing database " + databaseId); + } + synchronized (databaseMapLocker) { + + if (databaseMap.isEmpty() && databaseWorkerPool != null) { + if (LogLevel.hasSqlLevel(database.logLevel)) { + Log.d(TAG, database.getThreadLogPrefix() + "stopping thread"); + } + databaseWorkerPool.quit(); + databaseWorkerPool = null; + } + } + } + + @Override + public void onMethodCall(MethodCall call, Result result) { + switch (call.method) { + // quick testing + case METHOD_GET_PLATFORM_VERSION: + result.success("Android " + android.os.Build.VERSION.RELEASE); + break; + + case METHOD_CLOSE_DATABASE: { + onCloseDatabaseCall(call, result); + break; + } + case METHOD_QUERY: { + onQueryCall(call, result); + break; + } + case METHOD_INSERT: { + onInsertCall(call, result); + break; + } + case METHOD_UPDATE: { + onUpdateCall(call, result); + break; + } + case METHOD_EXECUTE: { + onExecuteCall(call, result); + break; + } + case METHOD_OPEN_DATABASE: { + onOpenDatabaseCall(call, result); + break; + } + case METHOD_BATCH: { + onBatchCall(call, result); + break; + } + case METHOD_OPTIONS: { + onOptionsCall(call, result); + break; + } + case METHOD_GET_DATABASES_PATH: { + onGetDatabasesPathCall(call, result); + break; + } + case METHOD_DELETE_DATABASE: { + onDeleteDatabaseCall(call, result); + break; + } + case METHOD_DEBUG: { + onDebugCall(call, result); + break; + } + case METHOD_QUERY_CURSOR_NEXT: { + onQueryCursorNextCall(call, result); + break; + } + case METHOD_DATABASE_EXISTS: { + onDatabaseExistsCall(call, result); + break; + } + // Obsolete + case METHOD_DEBUG_MODE: { + onDebugModeCall(call, result); + break; + } + case METHOD_ANDROID_SET_LOCALE: { + onSetLocaleCall(call, result); + break; + } + default: + result.notImplemented(); + break; + } + } + + void onOptionsCall(final MethodCall call, final Result result) { + Object threadPriority = call.argument(Constant.PARAM_THREAD_PRIORITY); + if (threadPriority != null) { + THREAD_PRIORITY = (Integer) threadPriority; + } + Object threadCount = call.argument(Constant.PARAM_THREAD_COUNT); + if (threadCount != null && !threadCount.equals(THREAD_COUNT)) { + THREAD_COUNT = (Integer) threadCount; + // Reset databaseWorkerPool when THREAD_COUNT change. + if (databaseWorkerPool != null) { + databaseWorkerPool.quit(); + databaseWorkerPool = null; + } + } + Integer logLevel = LogLevel.getLogLevel(call); + if (logLevel != null) { + SqflitePlugin.logLevel = logLevel; + } + result.success(null); + } + + //private static class Database + + void onGetDatabasesPathCall(final MethodCall call, final Result result) { + if (databasesPath == null) { + String dummyDatabaseName = "tekartik_sqflite.db"; + File file = context.getDatabasePath(dummyDatabaseName); + databasesPath = file.getParent(); + } + result.success(databasesPath); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqlCommand.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqlCommand.java new file mode 100644 index 0000000000000000000000000000000000000000..ab86bcd6a98afe416947b4c6c1b8a59f0ab34670 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/SqlCommand.java @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import android.database.sqlite.SQLiteProgram; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class SqlCommand { + final private String sql; + final private List rawArguments; + + public SqlCommand(String sql, List rawArguments) { + this.sql = sql; + if (rawArguments == null) { + rawArguments = new ArrayList<>(); + } + this.rawArguments = rawArguments; + } + + // Handle list of int as byte[] + static private Object toValue(Object value) { + if (value == null) { + return null; + } else { + // Assume a list is a blob + if (value instanceof List) { + @SuppressWarnings("unchecked") + List list = (List) value; + byte[] blob = new byte[list.size()]; + for (int i = 0; i < list.size(); i++) { + blob[i] = (byte) (int) list.get(i); + } + value = blob; + } + return value; + } + } + + public String getSql() { + return sql; + } + + private Object[] getSqlArguments(List rawArguments) { + List fixedArguments = new ArrayList<>(); + if (rawArguments != null) { + for (Object rawArgument : rawArguments) { + fixedArguments.add(toValue(rawArgument)); + } + } + return fixedArguments.toArray(new Object[0]); + } + + public void bindTo(SQLiteProgram statement) { + if (rawArguments != null) { + int count = rawArguments.size(); + for (int i = 0; i < count; i++) { + Object arg = toValue(rawArguments.get(i)); + // sqlite3 variables are 1-indexed + int sqlIndex = i + 1; + + if (arg == null) { + statement.bindNull(sqlIndex); + } else if (arg instanceof byte[]) { + statement.bindBlob(sqlIndex, (byte[]) arg); + } else if (arg instanceof Double) { + statement.bindDouble(sqlIndex, (Double) arg); + } else if (arg instanceof Integer) { + statement.bindLong(sqlIndex, (Integer) arg); + } else if (arg instanceof Long) { + statement.bindLong(sqlIndex, (Long) arg); + } else if (arg instanceof String) { + statement.bindString(sqlIndex, (String) arg); + } else if (arg instanceof Boolean) { + statement.bindLong(sqlIndex, ((Boolean) arg) ? 1 : 0); + } else { + throw new IllegalArgumentException("Could not bind " + arg + " from index " + + i + ": Supported types are null, byte[], double, long, boolean and String"); + } + } + } + } + + @Override + public String toString() { + return sql + ((rawArguments == null || rawArguments.isEmpty()) ? "" : (" " + rawArguments)); + } + + // As expected by execSQL + public Object[] getSqlArguments() { + return getSqlArguments(rawArguments); + } + + public List getRawSqlArguments() { + return rawArguments; + } + + @Override + public int hashCode() { + return sql != null ? sql.hashCode() : 0; + } + + @Override + public boolean equals(Object obj) { + if (obj instanceof SqlCommand) { + SqlCommand o = (SqlCommand) obj; + if (sql != null) { + if (!sql.equals(o.sql)) { + return false; + } + } else { + if (o.sql != null) { + return false; + } + } + + if (rawArguments.size() != o.rawArguments.size()) { + return false; + } + for (int i = 0; i < rawArguments.size(); i++) { + // special blob handling + if (rawArguments.get(i) instanceof byte[] && o.rawArguments.get(i) instanceof byte[]) { + if (!Arrays.equals((byte[]) rawArguments.get(i), (byte[]) o.rawArguments.get(i))) { + return false; + } + } else { + if (!rawArguments.get(i).equals(o.rawArguments.get(i))) { + return false; + } + } + } + return true; + } + return false; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Utils.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Utils.java new file mode 100644 index 0000000000000000000000000000000000000000..f770829d9227d337d3a257729027206a9cda1569 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/Utils.java @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static com.tekartik.sqflite.Constant.TAG; + +import android.database.Cursor; +import android.os.Build; +import android.util.Log; + +import androidx.annotation.RequiresApi; + +import com.tekartik.sqflite.dev.Debug; + +import java.util.ArrayList; +import java.util.List; +import java.util.Locale; + +public class Utils { + + static public List cursorRowToList(Cursor cursor, int length) { + List list = new ArrayList<>(length); + + for (int i = 0; i < length; i++) { + Object value = cursorValue(cursor, i); + if (Debug.EXTRA_LOGV) { + String type = null; + if (value != null) { + if (value.getClass().isArray()) { + type = "array(" + value.getClass().getComponentType().getName() + ")"; + } else { + type = value.getClass().getName(); + } + } + Log.d(TAG, "column " + i + " " + cursor.getType(i) + ": " + value + (type == null ? "" : " (" + type + ")")); + } + list.add(value); + } + return list; + } + + static public Object cursorValue(Cursor cursor, int index) { + switch (cursor.getType(index)) { + case Cursor.FIELD_TYPE_NULL: + return null; + case Cursor.FIELD_TYPE_INTEGER: + return cursor.getLong(index); + case Cursor.FIELD_TYPE_FLOAT: + return cursor.getDouble(index); + case Cursor.FIELD_TYPE_STRING: + return cursor.getString(index); + case Cursor.FIELD_TYPE_BLOB: + return cursor.getBlob(index); + } + return null; + } + + static Locale localeForLanguateTag(String localeString) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + return localeForLanguageTag21(localeString); + } else { + return localeForLanguageTagPre21(localeString); + } + } + + @RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) + static Locale localeForLanguageTag21(String localeString) { + return Locale.forLanguageTag(localeString); + } + + /** + * Really basic implementation, hopefully not so many dev/apps with such requirements + * should be impacted. + * + * @param localeString + * @return + */ + static Locale localeForLanguageTagPre21(String localeString) { + //Locale.Builder builder = new Locale().Builder(); + String[] parts = localeString.split("-"); + String language = ""; + String country = ""; + String variant = ""; + if (parts.length > 0) { + language = parts[0]; + if (parts.length > 1) { + country = parts[1]; + + if (parts.length > 2) { + variant = parts[parts.length - 1]; + } + } + } + return new Locale(language, country, variant); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/dev/Debug.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/dev/Debug.java new file mode 100644 index 0000000000000000000000000000000000000000..f2c0ac3c8ce20dd5d2aeb0e20cfc6c3839ee7897 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/dev/Debug.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.dev; + +import static android.content.ContentValues.TAG; + +import android.util.Log; + +/** + * Created by alex on 09/01/18. + */ + +public class Debug { + + // Log flags + public static boolean LOGV = false; + public static boolean _EXTRA_LOGV = false; // to set to true for type debugging + // public static boolean _EXTRA_LOGV = true; // to set to true for type debugging + static public boolean EXTRA_LOGV = false; // to set to true for type debugging + + // todo 已过时 + // Deprecated to prevent usage + @Deprecated + public static void devLog(String tag, String message) { + Log.d(TAG, message); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseOperation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..ccc544c3a826bde56b445335761c354803568c8b --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseOperation.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +/** + * Created by alex on 09/01/18. + */ + +public abstract class BaseOperation extends BaseReadOperation { + + // We actually have an inner object that does the implementation + protected abstract OperationResult getOperationResult(); + + @Override + public void success(Object result) { + getOperationResult().success(result); + } + + @Override + public void error(String errorCode, String errorMessage, Object data) { + getOperationResult().error(errorCode, errorMessage, data); + } + +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseReadOperation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseReadOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..3ebb9b97b7bd85ae53e9f7e7772cb03c02ba3ea1 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BaseReadOperation.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + + +import static com.tekartik.sqflite.Constant.PARAM_CONTINUE_OR_ERROR; +import static com.tekartik.sqflite.Constant.PARAM_IN_TRANSACTION_CHANGE; +import static com.tekartik.sqflite.Constant.PARAM_NO_RESULT; +import static com.tekartik.sqflite.Constant.PARAM_SQL; +import static com.tekartik.sqflite.Constant.PARAM_SQL_ARGUMENTS; +import static com.tekartik.sqflite.Constant.PARAM_TRANSACTION_ID; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.tekartik.sqflite.SqlCommand; + +import java.util.List; + +/** + * Created by alex on 09/01/18. + */ + +public abstract class BaseReadOperation implements Operation { + private String getSql() { + return getArgument(PARAM_SQL); + } + + private List getSqlArguments() { + return getArgument(PARAM_SQL_ARGUMENTS); + } + + @Nullable + public Integer getTransactionId() { + return getArgument(PARAM_TRANSACTION_ID); + } + + public boolean hasNullTransactionId() { + return hasArgument(PARAM_TRANSACTION_ID) && getTransactionId() == null; + } + + public SqlCommand getSqlCommand() { + return new SqlCommand(getSql(), getSqlArguments()); + } + + public Boolean getInTransactionChange() { + return getBoolean(PARAM_IN_TRANSACTION_CHANGE); + } + + @Override + public boolean getNoResult() { + return Boolean.TRUE.equals(getArgument(PARAM_NO_RESULT)); + } + + @Override + public boolean getContinueOnError() { + return Boolean.TRUE.equals(getArgument(PARAM_CONTINUE_OR_ERROR)); + } + + private Boolean getBoolean(String key) { + Object value = getArgument(key); + if (value instanceof Boolean) { + return (Boolean) value; + } + return null; + } + + // We actually have an inner object that does the implementation + protected abstract OperationResult getOperationResult(); + + @NonNull + @Override + public String toString() { + return "" + getMethod() + " " + getSql() + " " + getSqlArguments(); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BatchOperation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BatchOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..64e18fc09f8776019e637ec0bdd3b5b20fc1346e --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/BatchOperation.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +import static com.tekartik.sqflite.Constant.PARAM_ERROR; +import static com.tekartik.sqflite.Constant.PARAM_ERROR_CODE; +import static com.tekartik.sqflite.Constant.PARAM_ERROR_DATA; +import static com.tekartik.sqflite.Constant.PARAM_ERROR_MESSAGE; +import static com.tekartik.sqflite.Constant.PARAM_METHOD; +import static com.tekartik.sqflite.Constant.PARAM_RESULT; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import io.flutter.plugin.common.MethodChannel; + +/** + * Created by alex on 09/01/18. + */ + +public class BatchOperation extends BaseOperation { + final Map map; + final BatchOperationResult operationResult = new BatchOperationResult(); + final boolean noResult; + + public BatchOperation(Map map, boolean noResult) { + this.map = map; + this.noResult = noResult; + } + + @Override + public String getMethod() { + return (String) map.get(PARAM_METHOD); + } + + @SuppressWarnings("unchecked") + @Override + public T getArgument(String key) { + return (T) map.get(key); + } + + @Override + public boolean hasArgument(String key) { + return map.containsKey(key); + } + + @Override + public OperationResult getOperationResult() { + return operationResult; + } + + public Map getOperationSuccessResult() { + Map results = new HashMap<>(); + results.put(PARAM_RESULT, operationResult.result); + return results; + } + + public Map getOperationError() { + Map error = new HashMap<>(); + Map errorDetail = new HashMap<>(); + errorDetail.put(PARAM_ERROR_CODE, operationResult.errorCode); + errorDetail.put(PARAM_ERROR_MESSAGE, operationResult.errorMessage); + errorDetail.put(PARAM_ERROR_DATA, operationResult.errorData); + error.put(PARAM_ERROR, errorDetail); + return error; + } + + public void handleError(MethodChannel.Result result) { + result.error(this.operationResult.errorCode, this.operationResult.errorMessage, this.operationResult.errorData); + } + + @Override + public boolean getNoResult() { + return noResult; + } + + public void handleSuccess(List> results) { + if (!getNoResult()) { + results.add(getOperationSuccessResult()); + } + } + + public void handleErrorContinue(List> results) { + if (!getNoResult()) { + results.add(getOperationError()); + } + } + + public class BatchOperationResult implements OperationResult { + // success + Object result; + + // error + String errorCode; + String errorMessage; + Object errorData; + + @Override + public void success(Object result) { + this.result = result; + } + + @Override + public void error(String errorCode, String errorMessage, Object data) { + this.errorCode = errorCode; + this.errorMessage = errorMessage; + this.errorData = data; + } + } + + +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/MethodCallOperation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/MethodCallOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..4bbd779edb45e5ac20091057ec4bc3cfce94f37e --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/MethodCallOperation.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +import io.flutter.plugin.common.MethodCall; +import io.flutter.plugin.common.MethodChannel; + +/** + * Operation for Method call + */ + +public class MethodCallOperation extends BaseOperation { + public final Result result; + final MethodCall methodCall; + + public MethodCallOperation(MethodCall methodCall, MethodChannel.Result result) { + this.methodCall = methodCall; + this.result = new Result(result); + } + + @Override + public String getMethod() { + return methodCall.method; + } + + @Override + public T getArgument(String key) { + return methodCall.argument(key); + } + + @Override + public boolean hasArgument(String key) { + return methodCall.hasArgument(key); + } + + @Override + public OperationResult getOperationResult() { + return result; + } + + class Result implements OperationResult { + + final MethodChannel.Result result; + + Result(MethodChannel.Result result) { + this.result = result; + } + + @Override + public void success(Object result) { + this.result.success(result); + } + + @Override + public void error(String errorCode, String errorMessage, Object data) { + result.error(errorCode, errorMessage, data); + } + + } + + +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/Operation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/Operation.java new file mode 100644 index 0000000000000000000000000000000000000000..93a988fc30149e9476c810dde89d4f9730899064 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/Operation.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +import androidx.annotation.Nullable; + +import com.tekartik.sqflite.SqlCommand; + +/** + * Created by alex on 09/01/18. + */ + +public interface Operation extends OperationResult { + + String getMethod(); + + T getArgument(String key); + + boolean hasArgument(String key); + + SqlCommand getSqlCommand(); + + boolean getNoResult(); + + // In batch, means ignoring the error + boolean getContinueOnError(); + + // Only for execute command, true when entering a transaction, false when exiting + Boolean getInTransactionChange(); + + /** + * transaction id if any, only for within a transaction + */ + @Nullable + Integer getTransactionId(); + + /** + * Transaction v2 support + */ + boolean hasNullTransactionId(); +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationResult.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationResult.java new file mode 100644 index 0000000000000000000000000000000000000000..8ba31cbfa40373e6aee260a24c26b3ec14d98fdf --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationResult.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +import androidx.annotation.Nullable; + +/** + * Created by alex on 09/01/18. + */ + +public interface OperationResult { + void error(final String errorCode, final String errorMessage, final Object data); + + void success(@Nullable final Object result); +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationRunnable.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationRunnable.java new file mode 100644 index 0000000000000000000000000000000000000000..0092150e49d31aebc9024def6830913bd318a3ac --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/OperationRunnable.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +/** + * Operation runnable interface + */ +public interface OperationRunnable { + boolean run(); +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/QueuedOperation.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/QueuedOperation.java new file mode 100644 index 0000000000000000000000000000000000000000..fc03211a7a0bc145bf6f9b27ad9c826c2b36274c --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/QueuedOperation.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +public class QueuedOperation { + final Operation operation; + final Runnable runnable; + + public QueuedOperation(Operation operation, Runnable runnable) { + this.operation = operation; + this.runnable = runnable; + } + + public void run() { + runnable.run(); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/SqlErrorInfo.java b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/SqlErrorInfo.java new file mode 100644 index 0000000000000000000000000000000000000000..116f81d50c96c73e3fe0380221df97ce7373fc4a --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/main/java/com/tekartik/sqflite/operation/SqlErrorInfo.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite.operation; + +import static com.tekartik.sqflite.Constant.PARAM_SQL; +import static com.tekartik.sqflite.Constant.PARAM_SQL_ARGUMENTS; + +import com.tekartik.sqflite.SqlCommand; + +import java.util.HashMap; +import java.util.Map; + +public class SqlErrorInfo { + + static public Map getMap(Operation operation) { + Map map = null; + SqlCommand command = operation.getSqlCommand(); + if (command != null) { + map = new HashMap<>(); + map.put(PARAM_SQL, command.getSql()); + map.put(PARAM_SQL_ARGUMENTS, command.getRawSqlArguments()); + } + return map; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/ConstantTest.java b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/ConstantTest.java new file mode 100644 index 0000000000000000000000000000000000000000..4098d1ccd78bcb5732241dada77e97553a94cfb0 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/ConstantTest.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static org.junit.Assert.assertEquals; + +import org.junit.Test; + +/** + * Constants between dart & Java world + */ + +public class ConstantTest { + + @Test + public void key() { + assertEquals("com.tekartik.sqflite", Constant.PLUGIN_KEY); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/DatabaseWorkerPoolTest.java b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/DatabaseWorkerPoolTest.java new file mode 100644 index 0000000000000000000000000000000000000000..111ee42886311b4ba76826204f075957f95f4b9e --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/DatabaseWorkerPoolTest.java @@ -0,0 +1,202 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static org.junit.Assert.assertEquals; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashSet; +import java.util.Queue; +import java.util.Set; + +public class DatabaseWorkerPoolTest { + + private FakeDatabaseWorkerPool pool; + private FakeDatabaseWorker worker1; + private FakeDatabaseWorker worker2 ; + private FakeDatabase database1; + private FakeDatabase database2; + + @Before + public void setUp() { + pool = new FakeDatabaseWorkerPool("pool", 2, 0); + pool.start(); + worker1 = pool.getWorker(0); + worker2 = pool.getWorker(1); + database1 = new FakeDatabase(1); + database2 = new FakeDatabase(2); + } + + @After + public void tearDown() { + pool.quit(); + } + + @Test + public void tasksOfOneDBRunFIFO() { + // Arrange. + DatabaseTask task1 = new DatabaseTask(database1, () -> {}); + DatabaseTask task2 = new DatabaseTask(database1, () -> {}); + DatabaseTask task3 = new DatabaseTask(database2, () -> {}); + + + // Act. Posting three tasks. The first two are belonging to the same database. + pool.post(task1); + pool.post(task2); // It should not be started until task1 is done. + pool.post(task3); + + // Assert. Worker1 run task1. Worker2 skipped task2 and run task3. + assertEquals(Arrays.asList(task1), new ArrayList<>(worker1.tasks)); + assertEquals(Arrays.asList(task3), new ArrayList<>(worker2.tasks)); + + // Act. Worker1 and worker2 finished one task. + worker1.work(); + worker2.work(); + + // Assert. Worker1 run task2. + assertEquals(Arrays.asList(task2), new ArrayList<>(worker1.tasks)); + assertEquals(Collections.emptyList(), new ArrayList<>(worker2.tasks)); + } + + @Test + public void tasksOfOneTransactionRunByOneWorker() { + // Arrange. + DatabaseTask task1 = new DatabaseTask(database1, () -> {}); + database2.inTransaction = true; + DatabaseTask task2 = new DatabaseTask(database2, () -> {}); + + + // Act. Posting two tasks. + pool.post(task1); + pool.post(task2); + + // Assert. Worker1 run task1. Worker2 run task2 in transaction. + assertEquals(Arrays.asList(task1), new ArrayList<>(worker1.tasks)); + assertEquals(Arrays.asList(task2), new ArrayList<>(worker2.tasks)); + + // Act. Worker1 and worker2 finished one task. Then post a new task in the same transaction. + worker1.work(); + worker2.work(); + DatabaseTask task3 = new DatabaseTask(database2, () -> {}); + pool.post(task3); + + + // Assert. Worker1 was skipped. Worker2 run task2. + assertEquals(Collections.emptyList(), new ArrayList<>(worker1.tasks)); + assertEquals(Arrays.asList(task3), new ArrayList<>(worker2.tasks)); + } + + @Test + public void tasksOfDiffTransactionsRunByTwoWorker() { + // Arrange. + DatabaseTask task1 = new DatabaseTask(database1, () -> {}); + DatabaseTask task2 = new DatabaseTask(database2, () -> {}); + + // Act. Posting two tasks. + pool.post(task1); + pool.post(task2); + + // Assert. Worker1 run task1. Worker2 run task2. + assertEquals(Arrays.asList(task1), new ArrayList<>(worker1.tasks)); + assertEquals(Arrays.asList(task2), new ArrayList<>(worker2.tasks)); + + // Act. Worker1 and worker2 finished one task. Then post a new task. + worker1.work(); + worker2.work(); + DatabaseTask task3 = new DatabaseTask(database2, () -> {}); + pool.post(task3); + + + // Assert. Task3 is not in transaction. Just find the first available worker (worker1) + // to run task2. + assertEquals(Arrays.asList(task3), new ArrayList<>(worker1.tasks)); + assertEquals(Collections.emptyList(), new ArrayList<>(worker2.tasks)); + } +} + +class FakeDatabase implements DatabaseDelegate { + + final int databaseId; + boolean inTransaction; + + FakeDatabase(int databaseId) { + this.databaseId = databaseId; + } + + @Override + public int getDatabaseId() { + return databaseId; + } + + @Override + public boolean isInTransaction() { + return inTransaction; + } +} + +class FakeDatabaseWorker extends DatabaseWorker { + + Queue tasks = new ArrayDeque<>(); + + FakeDatabaseWorker(String name, int priority) { + super(name, priority); + } + + @Override + void start(Runnable onIdle) { + this.onIdle = onIdle; + } + + @Override + void quit() {} + + @Override + void postTask(final DatabaseTask task) { + tasks.add(task); + } + + void work() { + DatabaseTask task = tasks.remove(); + super.work(task); + } +} + +class FakeDatabaseWorkerPool extends DatabaseWorkerPoolImpl { + + final Set workers = new HashSet<>(); + + FakeDatabaseWorkerPool(String name, int numberOfWorkers, int priority) { + super(name, numberOfWorkers, priority); + } + + @Override + protected DatabaseWorker createWorker(String name, int priority) { + FakeDatabaseWorker worker = new FakeDatabaseWorker(name, priority); + workers.add(worker); + return worker; + } + + FakeDatabaseWorker getWorker(int idx) { + return new ArrayList<>(workers).get(idx); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/LogLevelTest.java b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/LogLevelTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8a0e8273df500b0dd5141571f14464124ea196fb --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/LogLevelTest.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +/** + * Constants between dart & Java world + */ + +public class LogLevelTest { + + + @Test + public void hasSqlLogLevel() { + assertTrue(LogLevel.hasSqlLevel(1)); + assertFalse(LogLevel.hasSqlLevel(0)); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/SqlCommandTest.java b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/SqlCommandTest.java new file mode 100644 index 0000000000000000000000000000000000000000..8df6d4c660fc7fca72f8d7227adc090c2e3f9b57 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/android/src/test/java/com/tekartik/sqflite/SqlCommandTest.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.tekartik.sqflite; + +import static org.junit.Assert.assertArrayEquals; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; + +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** + * Constants between dart & Java world + */ + +public class SqlCommandTest { + + + @Test + public void noParam() { + SqlCommand command = new SqlCommand(null, null); + assertEquals(command.getSql(), null); + assertEquals(command.getRawSqlArguments(), new ArrayList<>()); + } + + @Test + public void sqlArguments() { + List arguments = Arrays.asList((Object) 1L, 2, "text", + 1.234f, + 4.5678, // double + new byte[]{1, 2, 3}); + SqlCommand command = new SqlCommand(null, arguments); + /* + assertEquals(Arrays.asList(1L, 2, "text", + 1.234f, + 4.5678, // double + new byte[] {1,2, 3}), command.getRawSqlArguments()); + */ + assertArrayEquals(new Object[]{1L, 2, "text", + 1.234f, + 4.5678, // double + new byte[]{1, 2, 3}}, command.getSqlArguments()); + } + + @Test + public void equals() { + SqlCommand command1 = new SqlCommand(null, null); + SqlCommand command2 = new SqlCommand(null, new ArrayList()); + assertEquals(command1, command2); + command1 = new SqlCommand("", null); + assertNotEquals(command1, command2); + assertNotEquals(command2, command1); + command1 = new SqlCommand(null, Arrays.asList((Object) "test")); + assertNotEquals(command1, command2); + assertNotEquals(command2, command1); + command2 = new SqlCommand(null, Arrays.asList((Object) "test")); + assertEquals(command1, command2); + command1 = new SqlCommand(null, Arrays.asList((Object) "test_")); + assertNotEquals(command1, command2); + assertNotEquals(command2, command1); + command1 = new SqlCommand(null, Arrays.asList((Object) new byte[]{1, 2, 3})); + command2 = new SqlCommand(null, Arrays.asList((Object) new byte[]{1, 2, 3})); + assertEquals(command1, command2); + command1 = new SqlCommand(null, Arrays.asList((Object) new byte[]{1, 2})); + assertNotEquals(command1, command2); + assertNotEquals(command2, command1); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/sqflite.dart b/ohos/test_sqflite/lib/sqflite/lib/sqflite.dart new file mode 100644 index 0000000000000000000000000000000000000000..561baee871af99a2fe268d3425edad336c61c25f --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/sqflite.dart @@ -0,0 +1,103 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:sqflite/src/compat.dart'; +import 'package:sqflite/src/constant.dart'; +import 'package:sqflite/src/sqflite_android.dart'; +import 'package:sqflite/src/sqflite_impl.dart'; +import 'package:sqflite/src/utils.dart' as impl; +import 'package:sqflite/utils/utils.dart' as utils; + +import 'sqlite_api.dart'; + +export 'package:sqflite/sql.dart' show ConflictAlgorithm; +export 'package:sqflite/src/compat.dart'; +export 'package:sqflite_common/sqflite.dart'; + +export 'sqlite_api.dart'; +export 'src/factory_impl.dart' show databaseFactorySqflitePlugin; +export 'src/sqflite_plugin.dart' show SqflitePlugin; + +/// +/// sqflite plugin +/// +class Sqflite { + /// Turns on debug mode if you want to see the SQL query + /// executed natively. + @Deprecated('Removed in next major release') + static Future setDebugModeOn([bool on = true]) async { + await invokeMethod(methodSetDebugModeOn, on); + } + + /// Planned Deprecated for 1.1.7 + @Deprecated('Removed in next major release') + static Future getDebugModeOn() async { + return impl.debugModeOn; + } + + /// deprecated on purpose to remove from code. + /// + /// To use during developpment/debugging + /// Set extra dart and nativate debug logs + @Deprecated('Dev only') + static Future devSetDebugModeOn([bool on = true]) { + impl.debugModeOn = on; + return setDebugModeOn(on); + } + + /// Testing only. + /// + /// deprecated on purpose to remove from code. + @Deprecated('Dev only') + static Future devSetOptions(SqfliteOptions options) async { + await invokeMethod(methodOptions, options.toMap()); + } + + /// Testing only + @Deprecated('Dev only') + static Future devInvokeMethod(String method, + [Object? arguments]) async { + await invokeMethod(method, arguments); + } + + /// helper to get the first int value in a query + /// Useful for COUNT(*) queries + static int? firstIntValue(List> list) => + utils.firstIntValue(list); + + /// Utility to encode a blob to allow blob query using + /// 'hex(blob_field) = ?', Sqlite.hex([1,2,3]) + static String hex(List bytes) => utils.hex(bytes); + + /// Sqlite has a dead lock warning feature that will print some text + /// after 10s, you can override the default behavior + static void setLockWarningInfo( + {Duration? duration, void Function()? callback}) { + utils.setLockWarningInfo(duration: duration!, callback: callback!); + } +} + +/// Android only API +extension SqfliteDatabaseAndroidExt on Database { + /// Sets the locale for this database. The specified IETF BCP 47 language tag + /// string (en-US, zh-CN, fr-FR, zh-Hant-TW, ...) must be as defined in + /// `Locale.forLanguageTag` in Android/Java documentation. + /// + /// Only on Android. + Future androidSetLocale(String languageTag) => + SqfliteDatabaseAndroidExtImpl(this).androidSetLocale(languageTag); +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/sqflite_dev.dart b/ohos/test_sqflite/lib/sqflite/lib/sqflite_dev.dart new file mode 100644 index 0000000000000000000000000000000000000000..f9e6df7091ab38ce496517eb2d0feeedfd15c70a --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/sqflite_dev.dart @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:sqflite/src/factory.dart'; +import 'package:sqflite/src/factory_impl.dart'; +import 'package:sqflite_common/sqlite_api.dart'; + +export 'package:sqflite/src/factory_impl.dart' + show sqfliteDatabaseFactoryDefault; + +/// Change the default factory used. +/// +/// Test only. +/// +@visibleForTesting +void setMockDatabaseFactory(DatabaseFactory? factory) { + // ignore: invalid_use_of_visible_for_testing_member + sqfliteDatabaseFactory = factory as SqfliteDatabaseFactory?; +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/sql.dart b/ohos/test_sqflite/lib/sqflite/lib/sql.dart new file mode 100644 index 0000000000000000000000000000000000000000..8055f1120948241a8ebbcfda6dcfbfec449b2656 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/sql.dart @@ -0,0 +1,21 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Only export: +// * [ConflictAlgorithm] +// * [escapeName] +// * [unescapeName] +export 'package:sqflite/src/sql_builder.dart' + show ConflictAlgorithm, escapeName, unescapeName; diff --git a/ohos/test_sqflite/lib/sqflite/lib/sqlite_api.dart b/ohos/test_sqflite/lib/sqflite/lib/sqlite_api.dart new file mode 100644 index 0000000000000000000000000000000000000000..a649d1b27fe0d6575609daa65fec85ba7e32d53f --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/sqlite_api.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/sqlite_api.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/batch.dart b/ohos/test_sqflite/lib/sqflite/lib/src/batch.dart new file mode 100644 index 0000000000000000000000000000000000000000..856600e81ac017c7a049af0875235ee7537a0272 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/batch.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/batch.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/collection_utils.dart b/ohos/test_sqflite/lib/sqflite/lib/src/collection_utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..1f2028667a655ca7193fe0b403013f8137b215e5 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/collection_utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/collection_utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/compat.dart b/ohos/test_sqflite/lib/sqflite/lib/src/compat.dart new file mode 100644 index 0000000000000000000000000000000000000000..5333d862d84e6028884b8454d3d526e02567a010 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/compat.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/compat.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/constant.dart b/ohos/test_sqflite/lib/sqflite/lib/src/constant.dart new file mode 100644 index 0000000000000000000000000000000000000000..3bbe1480b072a4d7592aca4ed43b3192fadf2297 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/constant.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/constant.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/database.dart b/ohos/test_sqflite/lib/sqflite/lib/src/database.dart new file mode 100644 index 0000000000000000000000000000000000000000..509d67003490a86c5a1ef6a9793a98f00a7bd4c2 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/database.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/database.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/database_mixin.dart b/ohos/test_sqflite/lib/sqflite/lib/src/database_mixin.dart new file mode 100644 index 0000000000000000000000000000000000000000..c51b224dcd56f40ab0453c4e4422fe539ca0e890 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/database_mixin.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/database_mixin.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/dev_utils.dart b/ohos/test_sqflite/lib/sqflite/lib/src/dev_utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..c572b45c07e6ee0b6556f8a75d7dc4cbcd016cbd --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/dev_utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/dev_utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/env_utils.dart b/ohos/test_sqflite/lib/sqflite/lib/src/env_utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..147362198e146aecea122f4b275801026f2bf71d --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/env_utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/env_utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/exception.dart b/ohos/test_sqflite/lib/sqflite/lib/src/exception.dart new file mode 100644 index 0000000000000000000000000000000000000000..2c5a86939396356c84f53475289baeb13de571e4 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/exception.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/exception.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/exception_impl.dart b/ohos/test_sqflite/lib/sqflite/lib/src/exception_impl.dart new file mode 100644 index 0000000000000000000000000000000000000000..1964af005ca15f32984fe61df9b1e0152a7c449c --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/exception_impl.dart @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite/src/services_impl.dart'; +import 'package:sqflite/src/sqflite_import.dart'; + +/// Wrap any exception to a [DatabaseException] +Future wrapDatabaseException(Future Function() action) async { + try { + final result = await action(); + return result; + } on PlatformException catch (e) { + if (e.code == sqliteErrorCode) { + throw SqfliteDatabaseException(e.message!, e.details); + //rethrow; + } else { + rethrow; + } + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/factory.dart b/ohos/test_sqflite/lib/sqflite/lib/src/factory.dart new file mode 100644 index 0000000000000000000000000000000000000000..cf549aea94a271322cb0d16424f98cee0eff2abf --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/factory.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/factory.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/factory_impl.dart b/ohos/test_sqflite/lib/sqflite/lib/src/factory_impl.dart new file mode 100644 index 0000000000000000000000000000000000000000..8cc7ad5528e51728d6b141ad94fd8ed827bb8792 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/factory_impl.dart @@ -0,0 +1,72 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/foundation.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:sqflite/src/exception_impl.dart' as impl; +import 'package:sqflite/src/sqflite_impl.dart' as impl; +import 'package:sqflite/src/sqflite_import.dart'; +import 'package:sqflite_common/sqflite.dart' as sqflite_common; +import 'dev_utils.dart'; // ignore: unused_import + +/// sqflite Default factory +@visibleForTesting +SqfliteDatabaseFactory get sqfliteDatabaseFactory => + // ignore: invalid_use_of_visible_for_testing_member + (databaseFactoryOrNull ?? databaseFactorySqflitePlugin) + as SqfliteDatabaseFactory; + +final SqfliteDatabaseFactory _databaseFactorySqflitePlugin = + SqfliteDatabaseFactoryImpl(); + +/// Default factory that uses the plugin. +DatabaseFactory get databaseFactorySqflitePlugin => + _databaseFactorySqflitePlugin; + +/// Default factory that uses the plugin. +final sqfliteDatabaseFactoryDefault = _databaseFactorySqflitePlugin; + +/// Change the default factory. test only. +@visibleForTesting +set sqfliteDatabaseFactory(SqfliteDatabaseFactory? databaseFactory) => + sqflite_common.databaseFactory = databaseFactory; + +/// Factory implementation +class SqfliteDatabaseFactoryImpl with SqfliteDatabaseFactoryMixin { + /// Only to set for extra debugging + //static var _debugInternals = devWarning(true); + static const _debugInternals = false; + + @override + Future wrapDatabaseException(Future Function() action) => + impl.wrapDatabaseException(action); + + @override + Future invokeMethod(String method, [Object? arguments]) => + !_debugInternals + ? impl.invokeMethod(method, arguments) + : _invokeMethodWithLog(method, arguments); + + Future _invokeMethodWithLog(String method, [Object? arguments]) async { + // ignore: avoid_print + print('-> $method $arguments'); + final result = await impl.invokeMethod(method, arguments); + // ignore: avoid_print + print('<- $result'); + return result; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/factory_mixin.dart b/ohos/test_sqflite/lib/sqflite/lib/src/factory_mixin.dart new file mode 100644 index 0000000000000000000000000000000000000000..b715adb99a8b918d921c204e4c0b9b0e5499478e --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/factory_mixin.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/factory_mixin.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/messages.g.dart b/ohos/test_sqflite/lib/sqflite/lib/src/messages.g.dart new file mode 100644 index 0000000000000000000000000000000000000000..65bb7f64b0d511affa941deb083729859bf62436 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/messages.g.dart @@ -0,0 +1,372 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright 2013 The Flutter Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// Autogenerated from Pigeon (v9.2.4), do not edit directly. +// See also: https://pub.dev/packages/pigeon +// ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import + +import 'dart:async'; +import 'dart:convert'; +import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List; + +import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; +import 'package:flutter/services.dart'; + +class SqfliteApi { + /// Constructor for [SqfliteApi]. The [binaryMessenger] named argument is + /// available for dependency injection. If it is left null, the default + /// BinaryMessenger will be used which routes to the host platform. + SqfliteApi({BinaryMessenger? binaryMessenger}) : _binaryMessenger = binaryMessenger; + final BinaryMessenger? _binaryMessenger; + + static const MessageCodec codec = StandardMessageCodec(); + + Future getPlatformVersion([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.getPlatformVersion', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(" ") as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + Future onCloseDatabaseCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.closeDatabase', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + // query + Future onQueryCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.query', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //insert + Future onInsertCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.insert', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //update + Future onUpdateCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.update', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //execute + Future onExecuteCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.execute', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //openDatabase + Future onOpenDatabaseCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.openDatabase', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //batch + Future onBatchCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.batch', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //options + Future onOptionsCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.options', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //getDatabasesPath + Future onGetDatabasesPathCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.getDatabasesPath', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //deleteDatabase + Future onDeleteDatabaseCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.deleteDatabase', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //debugMode + Future onDebugCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.debugMode', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //queryCursorNext + Future onQueryCursorNextCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.queryCursorNext', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //databaseExists + Future onDatabaseExistsCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.databaseExists', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //debugMode + Future onDebugModeCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.debugMode', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } + + //androidSetLocale + Future onSetLocaleCall([Object? arguments]) async { + final BasicMessageChannel channel = + BasicMessageChannel('dev.flutter.pigeon.SqfliteApi.androidSetLocale', codec, binaryMessenger: _binaryMessenger); + final List? replyList = await channel.send(arguments) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else { + return (replyList[0]); + } + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/mixin.dart b/ohos/test_sqflite/lib/sqflite/lib/src/mixin.dart new file mode 100644 index 0000000000000000000000000000000000000000..33ac23f1f8a74538a68ce2e8436e40fa98621763 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/mixin.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/mixin.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/mixin/constant.dart b/ohos/test_sqflite/lib/sqflite/lib/src/mixin/constant.dart new file mode 100644 index 0000000000000000000000000000000000000000..b8336053b74f3ba2d0c2afd7ad348682f92d342c --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/mixin/constant.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/mixin/constant.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/mixin/factory.dart b/ohos/test_sqflite/lib/sqflite/lib/src/mixin/factory.dart new file mode 100644 index 0000000000000000000000000000000000000000..169ce2913adeba0972ed768879c6d20ba4a99f3b --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/mixin/factory.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/mixin/factory.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/ohos_extension.dart b/ohos/test_sqflite/lib/sqflite/lib/src/ohos_extension.dart new file mode 100644 index 0000000000000000000000000000000000000000..ef0211385a69d54d98d6ef082f6d6fd622c0a8bd --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/ohos_extension.dart @@ -0,0 +1,33 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +abstract class Constant { + static const String METHOD_GET_PLATFORM_VERSION = 'getPlatformVersion'; + static const String METHOD_CLOSE_DATABASE = 'closeDatabase'; + static const String METHOD_QUERY = 'query'; + static const String METHOD_INSERT = 'insert'; + static const String METHOD_UPDATE = 'update'; + static const String METHOD_EXECUTE = 'execute'; + static const String METHOD_OPEN_DATABASE = 'openDatabase'; + static const String METHOD_BATCH = 'batch'; + static const String METHOD_OPTIONS = 'options'; + static const String METHOD_GET_DATABASES_PATH = 'getDatabasesPath'; + static const String METHOD_DELETE_DATABASE = 'deleteDatabase'; + static const String METHOD_DEBUG = 'debug'; + static const String METHOD_QUERY_CURSOR_NEXT = 'queryCursorNext'; + static const String METHOD_DATABASE_EXISTS = 'databaseExists'; + static const String METHOD_DEBUG_MODE = 'debugMode'; + static const String METHOD_ANDROID_SET_LOCALE = 'androidSetLocale'; +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/open_options.dart b/ohos/test_sqflite/lib/sqflite/lib/src/open_options.dart new file mode 100644 index 0000000000000000000000000000000000000000..5a61eecf0887d424d9611c964a79446ee9b29360 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/open_options.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/open_options.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/services_impl.dart b/ohos/test_sqflite/lib/sqflite/lib/src/services_impl.dart new file mode 100644 index 0000000000000000000000000000000000000000..01cc657f61098b252052eefc370c03707d6d79a2 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/services_impl.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:flutter/services.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_android.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_android.dart new file mode 100644 index 0000000000000000000000000000000000000000..621e4829b4b55ee1ecad274d1401e73b08dd81ec --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_android.dart @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite/src/sqflite_import.dart'; +import 'package:sqflite_common/sqlite_api.dart'; + +import 'constant.dart'; + +/// Native Android setLocale call. +const String methodAndroidSetLocale = 'androidSetLocale'; + +/// Locale param. +const String paramLocale = 'locale'; + +/// Private implementation in an extension for Android only +extension SqfliteDatabaseAndroidExtImpl on Database { + SqfliteDatabaseMixin get _mixin => this as SqfliteDatabaseMixin; + + /// Set the locale. + Future androidSetLocale(String languageTag) async { + await _mixin.safeInvokeMethod(methodAndroidSetLocale, + {paramId: _mixin.id, paramLocale: languageTag}); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_compat.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_compat.dart new file mode 100644 index 0000000000000000000000000000000000000000..4791a0cca90821483765462bee82a5d5324f0fdc --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_compat.dart @@ -0,0 +1,79 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:sqflite/src/compat.dart'; +import 'package:sqflite/src/constant.dart'; +import 'package:sqflite/src/sqflite_impl.dart'; +import 'package:sqflite/src/utils.dart' as impl; +import 'package:sqflite/utils/utils.dart' as utils; + +/// +/// sqflite plugin. Might be deprecated/removed in the future. +/// +class Sqflite { + /// Turns on debug mode if you want to see the SQL query + /// executed natively. + static Future setDebugModeOn([bool on = true]) async { + await invokeMethod(methodSetDebugModeOn, on); + } + + /// Planned Deprecated for 1.1.7 + static Future getDebugModeOn() async { + return impl.debugModeOn; + } + + /// deprecated on purpose to remove from code. + /// + /// To use during developpment/debugging + /// Set extra dart and nativate debug logs + @Deprecated('Dev only') + static Future devSetDebugModeOn([bool on = true]) { + impl.debugModeOn = on; + return setDebugModeOn(on); + } + + /// Testing only. + /// + /// deprecated on purpose to remove from code. + @Deprecated('Dev only') + static Future devSetOptions(SqfliteOptions options) async { + await invokeMethod(methodOptions, options.toMap()); + } + + /// Testing only + @Deprecated('Dev only') + static Future devInvokeMethod(String method, + [Object? arguments]) async { + await invokeMethod(method, arguments); + } + + /// helper to get the first int value in a query + /// Useful for COUNT(*) queries + static int? firstIntValue(List> list) => + utils.firstIntValue(list); + + /// Utility to encode a blob to allow blob query using + /// 'hex(blob_field) = ?', Sqlite.hex([1,2,3]) + static String hex(List bytes) => utils.hex(bytes); + + /// Sqlite has a dead lock warning feature that will print some text + /// after 10s, you can override the default behavior + static void setLockWarningInfo( + {Duration? duration, void Function()? callback}) { + utils.setLockWarningInfo(duration: duration!, callback: callback!); + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_impl.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_impl.dart new file mode 100644 index 0000000000000000000000000000000000000000..c74af15b26c5a08beb7600539d3b1348996beefe --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_impl.dart @@ -0,0 +1,31 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:core'; + +import 'services_impl.dart'; + +/// Sqflite channel name +const String channelName = 'com.tekartik.sqflite'; + +/// Sqflite channel +const MethodChannel channel = MethodChannel(channelName); + +/// Temp flag to test concurrent reads +const supportsConcurrency = false; + +/// Invoke a native method +Future invokeMethod(String method, [Object? arguments]) async => + await channel.invokeMethod(method, arguments) as T; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_import.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_import.dart new file mode 100644 index 0000000000000000000000000000000000000000..2304f58b821051966086e25592efd468f386b415 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_import.dart @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +/// +/// Export for implementation: sqflite, sqflite_common_ffi +/// +export 'package:sqflite_common/src/compat.dart' + show SqfliteOptions; // ignore: deprecated_member_use +/// Explicit list of needed private import +export 'package:sqflite_common/src/database.dart' // ignore: implementation_imports + show + SqfliteDatabaseOpenHelper, + SqfliteDatabase; +export 'package:sqflite_common/src/database_mixin.dart' // ignore: implementation_imports + show + SqfliteDatabaseMixin, + SqfliteDatabaseBase; +export 'package:sqflite_common/src/exception.dart' + show SqfliteDatabaseException; +export 'package:sqflite_common/src/factory.dart' show SqfliteDatabaseFactory; +export 'package:sqflite_common/src/factory_mixin.dart' + show SqfliteDatabaseFactoryBase, SqfliteDatabaseFactoryMixin; +export 'package:sqflite_common/src/mixin/constant.dart' + show + methodOpenDatabase, + methodCloseDatabase, + methodOptions, + sqliteErrorCode, + methodInsert, + methodQuery, + methodUpdate, + methodExecute, + methodBatch; +export 'package:sqflite_common/src/mixin/factory.dart' + show buildDatabaseFactory, SqfliteInvokeHandler; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_plugin.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_plugin.dart new file mode 100644 index 0000000000000000000000000000000000000000..38aa194aeb1b8620704c94bf3b01bd4aea0eae7d --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sqflite_plugin.dart @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite/sqflite.dart'; + +import 'factory_impl.dart'; + +/// sqflite Plugin registration. +class SqflitePlugin { + /// Registers this plugin as the default database factory (if not already set). + static void registerWith() { + databaseFactoryOrNull ??= sqfliteDatabaseFactoryDefault; + } +} diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/sql_builder.dart b/ohos/test_sqflite/lib/sqflite/lib/src/sql_builder.dart new file mode 100644 index 0000000000000000000000000000000000000000..e5a7a40d9bd54324e676d7d68c1c8fc97227ade4 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/sql_builder.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/sql_builder.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/transaction.dart b/ohos/test_sqflite/lib/sqflite/lib/src/transaction.dart new file mode 100644 index 0000000000000000000000000000000000000000..301fbd87659201a243981ee7eff5cf092c9a76ac --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/transaction.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/transaction.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/utils.dart b/ohos/test_sqflite/lib/sqflite/lib/src/utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..25240d1801cddb6587bce86dc5bf3d9b246b1ea1 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/src/value_utils.dart b/ohos/test_sqflite/lib/sqflite/lib/src/value_utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..0f407f73983bdf8256fdad4e7ec0802afe26b669 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/src/value_utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/src/value_utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/lib/utils/utils.dart b/ohos/test_sqflite/lib/sqflite/lib/utils/utils.dart new file mode 100644 index 0000000000000000000000000000000000000000..c5ff84276b3e6cd116f0e2603a4998a51ddcfb69 --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/lib/utils/utils.dart @@ -0,0 +1,16 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export 'package:sqflite_common/utils/utils.dart'; diff --git a/ohos/test_sqflite/lib/sqflite/pubspec.yaml b/ohos/test_sqflite/lib/sqflite/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..47c2c71a0dae3d42a1e2256eff3c6e7cff8234cb --- /dev/null +++ b/ohos/test_sqflite/lib/sqflite/pubspec.yaml @@ -0,0 +1,66 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: sqflite +repository: https://github.com/tekartik/sqflite/tree/master/sqflite +issue_tracker: https://github.com/tekartik/sqflite/issues +description: Flutter plugin for SQLite, a self-contained, high-reliability, + embedded, SQL database engine. +version: 2.2.8+4 +funding: + - https://github.com/sponsors/alextekartik + +environment: + sdk: '>=2.18.0 <4.0.0' + flutter: ">=3.3.0" + +flutter: + plugin: + platforms: + android: + package: com.tekartik.sqflite + pluginClass: SqflitePlugin + dartPluginClass: SqflitePlugin + ios: + pluginClass: SqflitePlugin + dartPluginClass: SqflitePlugin + macos: + pluginClass: SqflitePlugin + dartPluginClass: SqflitePlugin + linux: + default_package: sqflite_ohos +# ohos: +# default_package: sqflite_ohos +# package: io.flutter.plugins.sqflite +# pluginClass: SqflitePlugin +# dartPluginClass: SqfliteOhos + +dependencies: + flutter: + sdk: flutter + sqflite_common: '>=2.4.5-3 <4.0.0' + path: '>=1.8.0 <3.0.0' + +dev_dependencies: + flutter_lints: '>=1.0.0' + process_run: '>=0.12.0' + http: '>=0.13.0' + flutter_test: + sdk: flutter + test_api: '>=0.2.19' + pub_semver: '>=2.0.0' +#dependency_overrides: +# sqflite_ohos: +# path: ../sqflite_ohos \ No newline at end of file diff --git a/ohos/test_sqflite/lib/src/no_flutter_main.dart b/ohos/test_sqflite/lib/src/no_flutter_main.dart new file mode 100644 index 0000000000000000000000000000000000000000..f8bb0d7522154ed4ea37c5e85fe55e3c89e99bc9 --- /dev/null +++ b/ohos/test_sqflite/lib/src/no_flutter_main.dart @@ -0,0 +1,44 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; +import 'package:sqflite/sqlite_api.dart'; +import 'package:sqflite/src/mixin/factory.dart'; + +import '../common/test_page.dart'; + +class no_flutter_mainTestPage extends TestPage { + no_flutter_mainTestPage(String title, {Key? key}) : super(title: title, key: key) { + final factory = buildDatabaseFactory(invokeMethod: (String method, [Object? arguments]) async { + Object? result; + // ignore: avoid_print + print('$method: $arguments'); + if (method == 'openDatabase') { + result = 1; + } else if (method == 'query' && (arguments as Map)['sql'] == 'PRAGMA user_version') { + result = {'user_version': 0}; + } + return result; + }); + run(factory); + } + + Future run(DatabaseFactory factory) async { + final db = await factory.openDatabase(inMemoryDatabasePath); + await db.getVersion(); + } +} diff --git a/ohos/test_sqflite/lib/src/no_flutter_test_.dart b/ohos/test_sqflite/lib/src/no_flutter_test_.dart new file mode 100644 index 0000000000000000000000000000000000000000..8c835802f9cd377618904e11f5e0b0a7398e9fe0 --- /dev/null +++ b/ohos/test_sqflite/lib/src/no_flutter_test_.dart @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter_test/flutter_test.dart'; + +// void main() { +// group('no_flutter', () { +// test('simple', () async { +// await run('dart test/no_flutter_main.dart'); +// }); +// }); +// } diff --git a/ohos/test_sqflite/lib/src/sqflite_dev_test.dart b/ohos/test_sqflite/lib/src/sqflite_dev_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..df7cc2097f4b6309ddf2f5e6bebaf3b226dd0f9c --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqflite_dev_test.dart @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:sqflite/sqflite.dart'; +import 'package:sqflite/sqflite_dev.dart'; + +import '../common/test_page.dart'; +import 'src_mixin_test.dart' show MockDatabaseFactoryEmpty; + +class sqflite_devTestPage extends TestPage { + sqflite_devTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('sqflite_dev', () { + test('setMockDatabaseFactory', () async { + final factory = MockDatabaseFactoryEmpty(); + expect(factory, databaseFactory); + try { + await openDatabase(inMemoryDatabasePath); + // expect(factory.methods.toString(), ['openDatabase']); + } finally { + + } + }); + + // Check that public api are exported + test('exported', () { + for (var value in [ + MockDatabaseFactoryEmpty, + ]) { + expect(value, value != null); + } + }); + }); + } +} diff --git a/ohos/test_sqflite/lib/src/sqflite_impl_test.dart b/ohos/test_sqflite/lib/src/sqflite_impl_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8494ccfcd62d1f7b4e506735164f8dc01505b669 --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqflite_impl_test.dart @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:sqflite/src/factory_impl.dart'; +import 'package:sqflite/src/mixin/factory.dart'; +import 'package:sqflite/src/sqflite_impl.dart'; + +import '../common/test_page.dart'; + +T? _ambiguate(T? value) => value; + +class sqflite_implTestPage extends TestPage { + sqflite_implTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('sqflite', () { + const channel = MethodChannel('com.tekartik.sqflite'); + + final log = []; + String? response; + + // _ambiguate(TestDefaultBinaryMessengerBinding.instance)! + // .defaultBinaryMessenger + // .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + // log.add(methodCall); + // return response; + // }); + + // tearDown(() { + log.clear(); + // }); + + test('databaseFactory', () async { + expect(databaseFactorySqflitePlugin is SqfliteInvokeHandler, true); + }); + + test('supportsConcurrency', () async { + expect(supportsConcurrency, false); + }); + + test('deprecated', () { + // sqfliteDatabaseFactory = null; + for (var element in [ + // ignore: unnecessary_statements + // sqfliteDatabaseFactory + ]) { + expect(element, element != null); + } + }); + }); + } +} diff --git a/ohos/test_sqflite/lib/src/sqflite_macos_impl_test.dart b/ohos/test_sqflite/lib/src/sqflite_macos_impl_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..8ef4ab13ded6a09a79f653c09bed0d17f6593b4b --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqflite_macos_impl_test.dart @@ -0,0 +1,52 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:io'; + +import 'package:flutter/cupertino.dart'; +import 'package:path/path.dart'; + +import '../common/test_page.dart'; + +Future testSameFileContent(String path1, String path2) async { + // print(path1); + expect(await File(path1).readAsString(), await File(path2).readAsString()); +} + +class sqflite_macos_implTestPage extends TestPage { + sqflite_macos_implTestPage(String title, { Key? key}) : super(title: title, key: key) { + group('macos', () { + test('ios/macos sample implementation,ios平台的测试, 这里报错正常', () async { + // Somehow we have either... + // sqflite + // or + // sqflite/test + var dir = Directory.current.path; + // print(dir); + if (basename(dir) == 'test') { + dir = dirname(dir); + } + final ios = join(dir, 'ios', 'Classes'); + final macos = join(dir, 'macos', 'Classes'); + for (var file in [ + ...['.h', '.m'].map((ext) => 'SqfliteOperation$ext'), + ...['.h', '.m'].map((ext) => 'SqflitePlugin$ext') + ]) { + await testSameFileContent(join(ios, file), join(macos, file)); + } + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/lib/src/sqflite_open_test.dart b/ohos/test_sqflite/lib/src/sqflite_open_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..7a5a3ccae18ceb8ecded0b4c9f5a94d63187a5b4 --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqflite_open_test.dart @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:sqflite/sqflite.dart'; + +import '../common/test_page.dart'; + +T? _ambiguate(T? value) => value; +const channel = MethodChannel('com.tekartik.sqflite'); + +class MockMethodCall { + String? expectedMethod; + dynamic expectedArguments; + dynamic response; + + @override + String toString() => '$expectedMethod $expectedArguments $response'; +} + +class MockScenario { + MockScenario(List data) { + methodsCalls = data + .map((list) => MockMethodCall() + ..expectedMethod = list[0]?.toString() + ..expectedArguments = list[1] + ..response = list[2]) + .toList(growable: false); + } + + late List methodsCalls; + var index = 0; + dynamic exception; + + void end() { + expect(exception, null); + expect(index, methodsCalls.length); + } +} + +MockScenario startScenario(List data) { + final scenario = MockScenario(data); + + // _ambiguate(TestDefaultBinaryMessengerBinding.instance)! + // .defaultBinaryMessenger + // .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + // final index = scenario.index++; + // // devPrint('$index ${scenario.methodsCalls[index]}'); + // final item = scenario.methodsCalls[index]; + // try { + // expect(methodCall.method, item.expectedMethod); + // expect(methodCall.arguments, item.expectedArguments); + // } catch (e) { + // scenario.exception ??= '$e $index'; + // } + // return item.response; + // }); + return scenario; +} + +class sqflite_openTestPage extends TestPage { + sqflite_openTestPage(String title, { Key? key}) : super(title: title, key: key) { + databaseFactory = databaseFactorySqflitePlugin; + + group('sqflite', () { + test('open single instance false', () async { + final scenario = startScenario([ + [ + 'openDatabase', + {'path': ':memory:', 'singleInstance': false}, + 1 + ], + [ + 'closeDatabase', + {'id': 1}, + null + ], + ]); + final db = await openDatabase(inMemoryDatabasePath); + await db.close(); + scenario.end(); + }); + test('open with version', () async { + final scenario = startScenario([ + [ + 'openDatabase', + {'path': ':memory:', 'singleInstance': false}, + 1 + ], + [ + 'query', + {'sql': 'PRAGMA user_version', 'id': 1}, + // ignore: inference_failure_on_collection_literal + {} + ], + [ + 'execute', + { + 'sql': 'BEGIN EXCLUSIVE', + 'id': 1, + 'transactionId': null, + 'inTransaction': true + }, + null + ], + [ + 'query', + {'sql': 'PRAGMA user_version', 'id': 1}, + // ignore: inference_failure_on_collection_literal + {} + ], + [ + 'execute', + {'sql': 'PRAGMA user_version = 1', 'id': 1}, + null + ], + [ + 'execute', + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + null + ], + [ + 'closeDatabase', + {'id': 1}, + null + ], + ]); + final db = await openDatabase(inMemoryDatabasePath, + version: 1, onCreate: (db, version) {}); + await db.close(); + scenario.end(); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite/lib/src/sqflite_test.dart b/ohos/test_sqflite/lib/src/sqflite_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fac705112cb352c0b134f77bae2e3ef11db6941 --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqflite_test.dart @@ -0,0 +1,157 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:sqflite/sqflite.dart'; + +import '../common/test_page.dart'; +import 'src_mixin_test.dart' show MockDatabaseFactoryEmpty, MockInvalidFactory; + +T? _ambiguate(T? value) => value; + +class sqfliteTestPage extends TestPage { + sqfliteTestPage(String title, {Key? key}) : super(title: title, key: key) { + databaseFactory = databaseFactorySqflitePlugin; + + group('sqflite', () { + const channel = MethodChannel('com.tekartik.sqflite'); + + final log = []; + String? response; + + // _ambiguate(TestDefaultBinaryMessengerBinding.instance)! + // .defaultBinaryMessenger + // .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + // log.add(methodCall); + // return response; + // }); + + // tearDown(() { + log.clear(); + // }); + + test('setDebugModeOn', () async { + // ignore: deprecated_member_use_from_same_package + await Sqflite.setDebugModeOn(); + log.add(const MethodCall('debugMode')); + expect(log.first.method, 'debugMode'); + expect(log.first.arguments, true); + }); + + // Check that public api are exported + test('exported', () { + for (var value in [ + // Not part of sqflite_api + openDatabase, + openReadOnlyDatabase, + getDatabasesPath, + deleteDatabase, + databaseExists, + Sqflite, + // ignore: deprecated_member_use, deprecated_member_use_from_same_package + SqfliteOptions, + // sqflite_api + OpenDatabaseOptions, + DatabaseFactory, + Database, + Transaction, + Batch, + ConflictAlgorithm, + // ignore: deprecated_member_use, deprecated_member_use_from_same_package + Sqflite.devSetOptions, + sqfliteLogLevelNone, + sqfliteLogLevelSql, + sqfliteLogLevelVerbose, + databaseFactory, + ]) { + expect(value, value != null); + } + }); + + test('firstIntValue', () { + expect( + Sqflite.firstIntValue(>[ + {'test': 1} + ]), + 1); + expect( + Sqflite.firstIntValue(>[ + {'test': 1}, + {'test': 1} + ]), + 1); + expect( + Sqflite.firstIntValue(>[ + {'test': null} + ]), + null); + expect(Sqflite.firstIntValue(>[{}]), + Sqflite.firstIntValue(>[{}]) != null); + expect(Sqflite.firstIntValue(>[]), Sqflite.firstIntValue(>[]) != null); + expect(Sqflite.firstIntValue(>[{}]), + Sqflite.firstIntValue(>[{}]) != null); + }); + + test('hex', () { + expect(Sqflite.hex([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 255]), '000102030405060708090A0B0C0D0E0F1011FF'); + expect(Sqflite.hex([]), ''); + expect(Sqflite.hex([32]), '20'); + + try { + Sqflite.hex([-1]); + fail('should fail'); + } on FormatException catch (_) {} + + try { + Sqflite.hex([256]); + fail('should fail'); + } on FormatException catch (_) {} + }); + + /* + test('open null', () async { + AssertionError? exception; + try { + await openDatabase(null!); + } on AssertionError catch (e) { + exception = e; + } + expect(exception, isNotNull); + }); + */ + + test('databaseFactory', () { + final originalDefaultFactory = databaseFactory; + try { + databaseFactory = null; + final factory = MockDatabaseFactoryEmpty(); + databaseFactory = factory; + expect(databaseFactory, factory); + expect(databaseFactory, (originalDefaultFactory)); + databaseFactory = originalDefaultFactory; // stderr trigger here + + try { + databaseFactory = MockInvalidFactory(); + fail('should fail'); + } on ArgumentError catch (_) {} + } finally { + databaseFactory = null; + databaseFactory = originalDefaultFactory; + } + }); + }); + } +} diff --git a/ohos/test_sqflite/lib/src/sql_test.dart b/ohos/test_sqflite/lib/src/sql_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..ec16f288f31473119fea92456f4a1b2737e7361e --- /dev/null +++ b/ohos/test_sqflite/lib/src/sql_test.dart @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/services.dart'; +import 'package:sqflite/sql.dart'; + +import '../common/test_page.dart'; + +T? _ambiguate(T? value) => value; + +class sqlTestPage extends TestPage { + sqlTestPage(String title, { Key? key}) : super(title: title, key: key) { + group('sqflite', () { + const channel = MethodChannel('com.tekartik.sqflite'); + + final log = []; + String? response; + + // _ambiguate(TestDefaultBinaryMessengerBinding.instance)! + // .defaultBinaryMessenger + // .setMockMethodCallHandler(channel, (MethodCall methodCall) async { + // log.add(methodCall); + // return response; + // }); + + // tearDown(() { + log.clear(); + // }); + + test('exported', () { + expect(ConflictAlgorithm.abort, ConflictAlgorithm.abort!=null); + }); + + test('escapeName_export', () { + expect(escapeName('group'), '"group"'); + }); + + test('unescapeName_export', () { + expect(unescapeName('"group"'), 'group'); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/lib/src/sqlite_api_test.dart b/ohos/test_sqflite/lib/src/sqlite_api_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..27349af46f63dd91aed1fb86c17ece4b5c92d9fc --- /dev/null +++ b/ohos/test_sqflite/lib/src/sqlite_api_test.dart @@ -0,0 +1,48 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:sqflite/sqlite_api.dart'; + +import '../common/test_page.dart'; + +class sqlite_apiTestPage extends TestPage { + sqlite_apiTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('sqlite_api', () { + // Check that public api are exported + test('exported', () { + for (var value in [ + OpenDatabaseOptions, + DatabaseFactory, + Database, + Transaction, + Batch, + ConflictAlgorithm, + inMemoryDatabasePath, + OnDatabaseConfigureFn, + OnDatabaseCreateFn, + OnDatabaseOpenFn, + OnDatabaseVersionChangeFn, + onDatabaseDowngradeDelete, + sqfliteLogLevelNone, + sqfliteLogLevelSql, + sqfliteLogLevelVerbose, + ]) { + expect(value, value != null); + } + }); + }); + } +} diff --git a/ohos/test_sqflite/lib/src/src_mixin_factory_test.dart b/ohos/test_sqflite/lib/src/src_mixin_factory_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..4a5440383d164a2cf2e18c54122344fba3f993ca --- /dev/null +++ b/ohos/test_sqflite/lib/src/src_mixin_factory_test.dart @@ -0,0 +1,46 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:sqflite/sqlite_api.dart'; +import 'package:sqflite/src/constant.dart'; +import 'package:sqflite/src/mixin/factory.dart'; + +import '../common/test_page.dart'; +import 'src_mixin_test.dart'; + +class src_mixin_factoryTestPage extends TestPage { + src_mixin_factoryTestPage(String title, { Key? key}) : super(title: title, key: key) { + group('mixin_factory', () { + test('public', () { + // ignore: unnecessary_statements + expect(buildDatabaseFactory, null); + // ignore: unnecessary_statements + expect(SqfliteInvokeHandler, null); + }); + test('buildDatabaseFactory', () async { + final methods = []; + final factory = buildDatabaseFactory( + invokeMethod: (String method, [Object? arguments]) async { + methods.add(method); + return mockResult(method); + }); + expect(factory is SqfliteInvokeHandler, true); + await factory.openDatabase(inMemoryDatabasePath); + expect(methods, ['openDatabase']); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/lib/src/src_mixin_test.dart b/ohos/test_sqflite/lib/src/src_mixin_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..5e6e1efc5a2ce4594ab286f4179bcc8023762c3b --- /dev/null +++ b/ohos/test_sqflite/lib/src/src_mixin_test.dart @@ -0,0 +1,813 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/cupertino.dart'; + +import 'package:test_sqflite/sqflite/lib/sqflite.dart'; +import 'package:test_sqflite/sqflite/lib/src/constant.dart'; +import 'package:test_sqflite/sqflite/lib/src/database.dart'; +import 'package:test_sqflite/sqflite/lib/src/database_mixin.dart'; +import 'package:test_sqflite/sqflite/lib/src/factory_mixin.dart'; +import 'package:path/path.dart'; +import '../common/test_page.dart'; +import '../sqflite/lib/src/open_options.dart'; +import '../sqflite/lib/utils/utils.dart'; + +class SrcMixinTestPage extends TestPage { + SrcMixinTestPage(String title, { Key? key}) : super(title: title, key: key) { + group('mixin_flutter', () { + run(); + }); + } + + final MockDatabaseFactory mockDatabaseFactory = MockDatabaseFactory(); + void run() { + group('database_factory', () { + test('getDatabasesPath', () async { + final factory = MockDatabaseFactoryEmpty(); + try { + await factory.getDatabasesPath(); + fail('should fail'); + } on DatabaseException catch (_) {} + expect(factory.methods, ['getDatabasesPath']); + //expect(directory, ) + }); + }); + group('database', () { + test('transaction', () async { + final Database db = mockDatabaseFactory.newEmptyDatabase(); + await db.execute('test'); + await db.insert('test', {'test': 1}); + await db.update('test', {'test': 1}); + await db.delete('test'); + await db.query('test'); + + await db.transaction((Transaction txn) async { + await txn.execute('test'); + await txn.insert('test', {'test': 1}); + await txn.update('test', {'test': 1}); + await txn.delete('test'); + await txn.query('test'); + }); + + final batch = db.batch(); + batch.execute('test'); + batch.insert('test', {'test': 1}); + batch.update('test', {'test': 1}); + batch.delete('test'); + batch.query('test'); + await batch.commit(); + }); + + group('open', () { + test('read-only', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase('test', + options: SqfliteOpenDatabaseOptions(readOnly: true)) + as MockDatabase; + await db.close(); + expect(db.methods, ['openDatabase', 'closeDatabase']); + expect(db.argumentsLists.first, { + 'path': absolute( + join(await mockDatabaseFactory.getDatabasesPath(), 'test')), + 'readOnly': true, + 'singleInstance': true + }); + }); + test('not single_instance', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase('single_instance.db', + options: SqfliteOpenDatabaseOptions(singleInstance: false)) + as MockDatabase; + await db.close(); + expect(db.methods, ['openDatabase', 'closeDatabase']); + expect(db.argumentsLists.first, { + 'path': absolute(join(await mockDatabaseFactory.getDatabasesPath(), + 'single_instance.db')), + 'singleInstance': false + }); + }); + + test('rollback transaction', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase( + 'rollback_transaction.db', + options: SqfliteOpenDatabaseOptions(singleInstance: false)) + as MockDatabase; + await db.execute('BEGIN TRANSACTION'); + await db.close(); + expect(db.methods, + ['openDatabase', 'execute', 'execute', 'closeDatabase']); + expect(db.argumentsLists.first, { + 'path': absolute(join(await mockDatabaseFactory.getDatabasesPath(), + 'rollback_transaction.db')), + 'singleInstance': false + }); + expect(db.argumentsLists[2], { + 'sql': 'ROLLBACK', + 'id': 1, + 'transactionId': -1, + 'inTransaction': false + }); + }); + test('isOpen', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase('is_open.db', + options: SqfliteOpenDatabaseOptions(readOnly: true)) + as MockDatabase; + expect(db.isOpen, true); + final closeFuture = db.close(); + // it is not closed right away + expect(db.isOpen, true); + await closeFuture; + expect(db.isOpen, false); + }); + + test('reOpenSameVersion', () async { + var db = await mockDatabaseFactory.openDatabase('on_reopen.db', + options: OpenDatabaseOptions( + version: 1, + )) as MockDatabase; + await db.close(); + + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + + db = await mockDatabaseFactory.openDatabase('on_reopen.db', + options: OpenDatabaseOptions( + version: 1, + )) as MockDatabase; + await db.close(); + + expect(db.sqls, [null, 'PRAGMA user_version', null]); + }); + }); + group('openTransaction', () { + test('onCreate', () async { + final db = await mockDatabaseFactory.openDatabase('on_create.db', + options: SqfliteOpenDatabaseOptions( + version: 1, + onCreate: (Database db, int version) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'query', + 'execute', + 'query', + 'execute', + 'execute', + 'execute', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'test1', + 'test2', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + }); + + test('onConfigure', () async { + final db = await mockDatabaseFactory.openDatabase('on_configure.db', + options: OpenDatabaseOptions( + version: 1, + onConfigure: (Database db) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'test1', + 'BEGIN IMMEDIATE', + 'test2', + 'COMMIT', + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + }); + + test('onOpen', () async { + final db = await mockDatabaseFactory.openDatabase('on_open', + options: OpenDatabaseOptions( + version: 1, + onOpen: (Database db) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + 'test1', + 'BEGIN IMMEDIATE', + 'test2', + 'COMMIT', + null + ]); + }); + + test('batch', () async { + final db = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions( + version: 1, + onConfigure: (Database db) async { + final batch = db.batch(); + batch.execute('test1'); + await batch.commit(); + }, + onCreate: (Database db, _) async { + final batch = db.batch(); + batch.execute('test2'); + await batch.commit(noResult: true); + }, + onOpen: (Database db) async { + final batch = db.batch(); + batch.execute('test3'); + await batch.commit(continueOnError: true); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'BEGIN IMMEDIATE', + 'test1', + 'COMMIT', + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'test2', + 'PRAGMA user_version = 1', + 'COMMIT', + 'BEGIN IMMEDIATE', + 'test3', + 'COMMIT', + null + ]); + expect(db.argumentsLists, [ + { + 'path': absolute( + join(await mockDatabaseFactory.getDatabasesPath(), 'test')), + 'singleInstance': true + }, + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'transactionId': null, + 'inTransaction': true + }, + { + 'operations': [ + { + 'method': 'execute', + 'sql': 'test1', + } + ], + 'id': 1 + }, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + {'sql': 'PRAGMA user_version', 'id': 1}, + { + 'sql': 'BEGIN EXCLUSIVE', + 'inTransaction': true, + 'transactionId': null, + 'id': 1 + }, + {'sql': 'PRAGMA user_version', 'id': 1}, + { + 'operations': >[ + { + 'method': 'execute', + 'sql': 'test2', + } + ], + 'id': 1, + 'noResult': true + }, + {'sql': 'PRAGMA user_version = 1', 'id': 1}, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null, + }, + { + 'operations': >[ + { + 'method': 'execute', + 'sql': 'test3', + } + ], + 'id': 1, + 'continueOnError': true + }, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + {'id': 1} + ]); + }); + }); + + group('concurrency', () { + test('concurrent 1', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db.execute('test').timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + // This is the change with concurrency 2 + await step1.future; + await db.transaction((Transaction txn) async { + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction((_) async {}); + }); + + test('concurrent 2', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db.execute('test').timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + await db.transaction((Transaction txn) async { + await step1.future; + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + }); + }); + + group('compatibility 1', () { + test('concurrent 1', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db.execute('test').timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + // This is the change with concurrency 2 + await step1.future; + await db.transaction((Transaction txn) async { + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction((_) async {}); + }); + + test('concurrent 2', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await step1.future; + try { + await db.execute('test').timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + await step2.future; + try { + await db.execute('test').timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + await db.transaction((Transaction txn) async { + step1.complete(); + + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future2 = action2(); + final Future future1 = action1(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction((_) async {}); + }); + }); + + group('batch', () { + test('simple', () async { + final db = await mockDatabaseFactory.openDatabase('batch_simple.db') + as MockDatabase; + + final batch = db.batch(); + batch.execute('test'); + await batch.commit(); + await batch.commit(); + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'execute', + 'batch', + 'execute', + 'execute', + 'batch', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, [ + null, + 'BEGIN IMMEDIATE', + 'test', + 'COMMIT', + 'BEGIN IMMEDIATE', + 'test', + 'COMMIT', + null + ]); + }); + + test('in_transaction', () async { + final db = await mockDatabaseFactory + .openDatabase('batch_in_transaction.db') as MockDatabase; + + await db.transaction((Transaction txn) async { + final batch = txn.batch(); + batch.execute('test'); + + await batch.commit(); + await batch.commit(); + }); + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'execute', + 'batch', + 'batch', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, + [null, 'BEGIN IMMEDIATE', 'test', 'test', 'COMMIT', null]); + }); + }); + + group('instances', () { + test('singleInstance same', () async { + final futureDb1 = mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)); + final db2 = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)) as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + expect(db1, db2); + }); + test('singleInstance', () async { + final futureDb1 = mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)); + final db2 = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)) as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + final db3 = await mockDatabaseFactory.openDatabase('other', + options: OpenDatabaseOptions(singleInstance: true)) as MockDatabase; + final db4 = await mockDatabaseFactory.openDatabase(join('.', 'other'), + options: OpenDatabaseOptions(singleInstance: true)) as MockDatabase; + //expect(db1, db2); + expect(db1, (db3)); + expect(db3, db4); + await db1.close(); + await db2.close(); + await db3.close(); + }); + + test('multiInstances', () async { + final futureDb1 = mockDatabaseFactory.openDatabase('multi_instances.db', + options: OpenDatabaseOptions(singleInstance: false)); + final db2 = await mockDatabaseFactory.openDatabase('multi_instances.db', + options: OpenDatabaseOptions(singleInstance: false)) + as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + expect(db1, (db2)); + await db1.close(); + await db2.close(); + }); + }); + + test('dead lock', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + var hasTimedOut = false; + var callbackCount = 0; + setLockWarningInfo( + duration: const Duration(milliseconds: 200), + callback: () { + callbackCount++; + }); + try { + await db.transaction((Transaction txn) async { + await db.execute('test'); + fail('should fail'); + }).timeout(const Duration(milliseconds: 500)); + } on TimeoutException catch (_) { + hasTimedOut = true; + } + expect(hasTimedOut, true); + expect(callbackCount, 1); + await db.close(); + }); + + test('deleted/exists', () async { + const path = 'test_exists.db'; + await mockDatabaseFactory.deleteDatabase(path); + final exists = await mockDatabaseFactory.databaseExists(path); + expect(exists, false); + final expectedPath = + absolute(join(await mockDatabaseFactory.getDatabasesPath(), path)); + expect(mockDatabaseFactory.methods, + ['deleteDatabase', 'databaseExists']); + expect(mockDatabaseFactory.argumentsList, >[ + {'path': expectedPath}, + {'path': expectedPath} + ]); + }); + }); + } +} +/// Mock the result based on the method used +dynamic mockResult(String method) { + // devPrint('$method'); + switch (method) { + case methodOpenDatabase: + return 1; + case methodInsert: + return 0; + case methodUpdate: + return 0; + case methodQuery: + return {}; + case methodDatabaseExists: + return false; + } + return null; +} + +class MockDatabase extends SqfliteDatabaseBase { + MockDatabase(SqfliteDatabaseOpenHelper openHelper, [String name = 'mock']) + : super(openHelper, name); + + int? version; + List methods = []; + List sqls = []; + List?> argumentsLists = ?>[]; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + // return super.invokeMethod(method, arguments); + + methods.add(method); + if (arguments is Map) { + argumentsLists.add(arguments.cast()); + if (arguments[paramOperations] != null) { + final operations = + arguments[paramOperations] as List>; + for (var operation in operations) { + final sql = operation[paramSql] as String?; + sqls.add(sql); + } + } else { + final sql = arguments[paramSql] as String?; + sqls.add(sql); + + // Basic version handling + if (sql?.startsWith('PRAGMA user_version = ') == true) { + version = int.tryParse(sql!.split(' ').last); + } else if (sql == 'PRAGMA user_version') { + return >[ + {'user_version': version} + ] as T; + } + } + } else { + argumentsLists.add(null); + sqls.add(null); + } + //devPrint('$method $arguments'); + return mockResult(method) as T; + } +} + +class MockDatabaseFactory extends SqfliteDatabaseFactoryBase { + final List methods = []; + final List argumentsList = []; + final Map databases = {}; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + methods.add(method); + argumentsList.add(arguments); + return mockResult(method) as T; + } + + SqfliteDatabase newEmptyDatabase() { + const path = 'empty'; + final helper = SqfliteDatabaseOpenHelper(this, path, OpenDatabaseOptions()); + final db = helper.newDatabase(path)..id = 1; + return db; + } + + @override + SqfliteDatabaseMixin newDatabase( + SqfliteDatabaseOpenHelper openHelper, String path) { + final existing = databases[path]; + final db = MockDatabase(openHelper, path); + // Copy version + db.version = existing?.version; + // Last replaces + databases[path] = db; + + return db; + } + + @override + Future getDatabasesPath() async { + return join('.dart_tool', 'sqlite', 'test', 'mock'); + } +} + +class MockDatabaseFactoryEmpty extends SqfliteDatabaseFactoryBase { + final List methods = []; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + methods.add(method); + return mockResult(method) as T; + } +} + +/// This unfortunately won't work, you must extends SqfliteDatabaseFactory +class MockInvalidFactory extends DatabaseFactory { + @override + Future databaseExists(String path) async { + return false; + } + + @override + Future deleteDatabase(String path) async {} + + @override + Future getDatabasesPath() async { + throw UnimplementedError(); + } + + @override + Future openDatabase(String path, + {OpenDatabaseOptions? options}) async { + throw UnimplementedError('openDatabase'); + } + + @override + Future setDatabasesPath(String path) { + throw UnimplementedError(); + } + +} + + + + diff --git a/ohos/test_sqflite/ohos/.gitignore b/ohos/test_sqflite/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_sqflite/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/AppScope/app.json5 b/ohos/test_sqflite/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..f9feb1f6eed1a5499719694979902e81579277b5 --- /dev/null +++ b/ohos/test_sqflite/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_sqflite", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_sqflite/ohos/AppScope/resources/base/element/string.json b/ohos/test_sqflite/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..37fe5da609a63261169621fe11763a0987ed19fb --- /dev/null +++ b/ohos/test_sqflite/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_sqflite" + } + ] +} diff --git a/ohos/test_sqflite/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_sqflite/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_sqflite/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_sqflite/ohos/build-profile.json5 b/ohos/test_sqflite/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..469deeac5c8e855f62e8aec9c3667986a8952fd4 --- /dev/null +++ b/ohos/test_sqflite/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite.cer", + "storePassword": "0000001B11608EBF3FB9710B242986B59804570BA1A5DEBC69D9DD3D7408D381043862413BDFAEE666D4BB", + "keyAlias": "debugKey", + "keyPassword": "0000001BEDF7283BAFC23519B3722722125C9A8FB262B997CB07A3E6AE5C08FCB797813CC382AF86FF34C0", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_sqflite/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_sqflite/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_sqflite/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_sqflite/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_sqflite/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_sqflite/ohos/dependencies/rollup.tgz b/ohos/test_sqflite/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_sqflite/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_sqflite/ohos/dta/icudtl.dat b/ohos/test_sqflite/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_sqflite/ohos/dta/icudtl.dat differ diff --git a/ohos/test_sqflite/ohos/entry/.gitignore b/ohos/test_sqflite/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/build-profile.json5 b/ohos/test_sqflite/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/hvigorfile.ts b/ohos/test_sqflite/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_sqflite/ohos/entry/oh-package.json5 b/ohos/test_sqflite/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..81cb4371e91cbec69aa0b3052b1d9d08674c4ca2 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,24 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' +import SqflitePlugin from '../sqflite/SqflitePlugin'; + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady(); + this.addPlugin(new SqflitePlugin()); + } +} diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..d784c75ed9d16a6657bb6466a148752b1b20bd91 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,26 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterPage } from '@ohos/flutter_ohos' + +@Entry +@Component +struct Index { + build() { + Column() { + FlutterPage() + } + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/Messages.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/Messages.ets new file mode 100644 index 0000000000000000000000000000000000000000..4668bdf0f48de8d8aa7673afbf7f8f215feb1c56 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/Messages.ets @@ -0,0 +1,422 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import BasicMessageChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; +import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; +import { SqlHelper } from './sql_helper'; + + +const TAG: string = "Message"; + +export default class Messages { + static wrapError(exception: Error): Array { + const errorList: Array = new Array(); + if (exception instanceof FlutterError) { + const error = exception; + errorList.push(error.code); + errorList.push(error.message); + errorList.push(error.details); + } else { + errorList.push(exception.name); + errorList.push(exception.message); + errorList.push(exception.stack); + } + return errorList; + } +} + +export class FlutterError extends Error { + code: string; + details: ESObject; + + constructor(code: string, message: string, details: ESObject) { + super(message); + this.code = code; + this.details = details; + } +} + +export abstract class SqfliteApi { + abstract getPlatformVersion(): string; + + /// 打开数据库 + abstract options(data: Map): Promise; + + /// 获取数据库存储的基本路径 + abstract getDatabasesPath(): string; + + /// 打开数据库 + abstract openDatabase(dataBaseName: string): Promise; + + /// 增加数据 + abstract insert(data: Map): Promise; + + /// 查询数据 + abstract query(data: Map): Promise>; + + /// 修改数据 + abstract update(data: Map): Promise; + + /// 关闭数据库 + abstract closeDatabase(dataBaseName: string): Promise; + + /// 删除数据库 + abstract deleteDatabase(dataBaseName: string): Promise; + + /// 执行sql语句 + abstract execute(data: Map): Promise; + + /// 检查数据库是否存在 + abstract databaseExists(dataBaseName: string): Promise; + + static getCodec(): MessageCodec { + return new StandardMessageCodec(); + } + + static setup(binaryMessenger: BinaryMessenger, api: SqfliteApi) { + Log.i(TAG, "鸿蒙setup成功 "); + { + Log.i(TAG, "鸿蒙options初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.options", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用options成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 options 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + await api.options(message as Map); + wrapped.push(null); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙getPlatformVersion初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.getPlatformVersion", + SqfliteApi.getCodec()); + if (api != null) { + + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用getPlatformVersion成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 getPlatformVersion 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + const output = api.getPlatformVersion(); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙getDatabasesPath初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.getDatabasesPath", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用getDatabasesPath成功 "); + let wrapped: Array = new Array(); + try { + const output = api.getDatabasesPath(); + Log.i(TAG, "getDatabasesPath 通道获取的数据: " + output as string); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙openDatabase初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.openDatabase", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用openDatabase成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 openDatabase 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + let dbName: string = SqlHelper.getLastPathName((message as Map).get('path')!.toString()); + const output = await api.openDatabase(dbName); + if (output >= 0) { + let returnMap = new Map(); + returnMap.set('id', output); + // todo 这里是不是需要自己写json返回去 + wrapped.push('{"id":1}'); + // wrapped.push(returnMap); + Log.i(TAG, "鸿蒙 openDatabase 通道创建数据库成功, 数据库id: " + output); + } else { + wrapped.push(null); + Log.i(TAG, "鸿蒙 openDatabase 通道创建数据库失败"); + } + } catch (err) { + Log.i(TAG, "鸿蒙 openDatabase 通道创建数据库在message出现异常: " + err); + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙insert初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.insert", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用insert成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 insert 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + const output = await api.insert(message as Map); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙query初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.query", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用query成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 query 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + const output = await api.query(message as Map); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + + { + Log.i(TAG, "鸿蒙update初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.update", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用update成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 update 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + const output = await api.update(message as Map); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + { + Log.i(TAG, "鸿蒙closeDatabase初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.closeDatabase", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用closeDatabase成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 closeDatabase 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + let dbName: string = SqlHelper.getLastPathName((message as Map).get('path') as string); + const output = await api.closeDatabase(dbName); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + + { + Log.i(TAG, "鸿蒙deleteDatabase初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.deleteDatabase", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用deleteDatabase成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 deleteDatabase 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + let dbName: string = SqlHelper.getLastPathName((message as Map).get('path') as string); + const output = await api.deleteDatabase(dbName); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + + { + Log.i(TAG, "鸿蒙execute初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.execute", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用execute成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 execute 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + const output = await api.execute(message as Map); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + + { + Log.i(TAG, "鸿蒙databaseExists初始化成功"); + const channel: BasicMessageChannel = + new BasicMessageChannel( + binaryMessenger, + "dev.flutter.pigeon.SqfliteApi.databaseExists", + SqfliteApi.getCodec()); + if (api != null) { + channel.setMessageHandler({ + onMessage: async (message: ESObject, reply: ESObject) => { + Log.i(TAG, "鸿蒙调用databaseExists成功 "); + let wrapped: Array = new Array(); + try { + Log.i(TAG, "鸿蒙 databaseExists 通道接收的数据: " + SqlHelper.mapToJson(message as Map)); + let dbName: string = SqlHelper.getLastPathName((message as Map).get('path') as string); + const output = await api.databaseExists(dbName); + wrapped.push(output); + } catch (err) { + const wrappedError: Array = Messages.wrapError(err); + wrapped = wrappedError; + } + reply.reply(wrapped); + } + }) + } else { + Log.i(TAG, "鸿蒙返回null "); + channel.setMessageHandler(null); + } + } + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/SqflitePlugin.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/SqflitePlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..22e30f4274a799917b6f5bacf7298f3a66a2bf3d --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/SqflitePlugin.ets @@ -0,0 +1,271 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; +import { + AbilityPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; +import { + FlutterPlugin, + FlutterPluginBinding +} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; +import { SqfliteApi } from './Messages'; +import { SqfLiteHelper } from './sqflite_helper'; +import relationalStore from '@ohos.data.relationalStore'; +import { ValueType } from '@ohos.data.ValuesBucket'; +import { SqlHelper } from './sql_helper'; + +const TAG: string = "SqflitePlugin"; + +export default class SqflitePlugin extends SqfliteApi implements FlutterPlugin, AbilityAware { + private pluginBinding: FlutterPluginBinding | null = null; + private context: common.Context | null = null; + + constructor(context?: common.Context) { + super(); + if (context) { + this.context = context; + } + } + + getUniqueClassName(): string { + return TAG; + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = binding; + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + this.pluginBinding = null; + } + + onAttachedToAbility(binding: AbilityPluginBinding): void { + Log.i(TAG, "flutter-sqflite-onAttachedToAbility"); + this.setup(this.pluginBinding!.getBinaryMessenger(), this.pluginBinding!.getApplicationContext()); + } + + onDetachedFromAbility(): void { + } + + static registerWith(): void { + } + + setup(messenger: BinaryMessenger, context: common.Context) { + try { + SqfliteApi.setup(messenger, this); + } catch (err) { + Log.e(TAG, "Received exception while setting up SqflitePlugin", err); + } + this.context = context; + } + + async options(data: Map): Promise { + data.forEach((value, key) => { + Log.i(TAG, 'options收到数据: ' + key + ' -> ' + value); + }) + } + + getPlatformVersion(): string { + Log.i(TAG, "HarmonyOS 通信正常"); + return "HarmonyOS 通信正常"; + } + + /// 获取数据库的路径 + getDatabasesPath(): string { + let path: string = this.context!.getApplicationContext().databaseDir; + Log.i(TAG, "鸿蒙 获取数据库路径:" + path); + /// EL1 + return path; + } + + /// 打开数据库 + async openDatabase(dataBaseName: string): Promise { + let id = await SqfLiteHelper.getDataBase(this.context!, dataBaseName) ?? -1; + Log.i(TAG, "鸿蒙 打开数据库结果:" + id); + return id; + } + + /// 插入数据 + async insert(data: Map): Promise { + Log.i(TAG, "鸿蒙 开始插入数据"); + + let rowId: number = -1; + let dbName: string = SqfLiteHelper.dBIdList.get(data.get('id')! as number) ?? ''; + Log.i(TAG, "鸿蒙 插入数据获取数据库名 :" + dbName); + let dataName: string[] = SqlHelper.getSqlDataName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 插入数据获取插入数据列 :" + dataName); + let tableName: string = SqlHelper.getInsertSqlTableName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 插入数据获取表名 :" + tableName); + + try { + Log.i(TAG, "鸿蒙 取到的arguments 1:" + JSON.stringify(data).toString()); + let txt: string = (data.get('arguments')! as string); + Log.i(TAG, "鸿蒙 取到的arguments 2:" + txt); + // let list: string[] = txt.split(",") as string[]; + // todo 这里的数据需要使用flutter传过来的才行 + let list: ValueType[] = [2, 'hi', 2000]; + Log.i(TAG, "鸿蒙 插入数据获取到的值:" + list.toString()); + const valuesBucket: relationalStore.ValuesBucket = {} + dataName.forEach((value, index) => { + valuesBucket[value] = list[index]; + }) + rowId = await SqfLiteHelper.insertData(dbName, tableName, valuesBucket); + Log.i(TAG, "鸿蒙 插入数据返回的行id:" + rowId); + } catch (e) { + Log.i(TAG, "鸿蒙 插入数据解析arguments出现异常" + e + rowId); + } + return rowId; + } + + /// 查询数据 + async query(data: Map): Promise> { + let returnMap: Map = new Map(); + let dbName: string = SqfLiteHelper.dBIdList.get(data.get('id')! as number) ?? ''; + Log.i(TAG, "鸿蒙 查询数据获取数据库名字 :" + dbName); + + if (dbName.length <= 0) { + Log.i(TAG, "鸿蒙 查询功能没有获取到数据库名字"); + return returnMap; + } + + if ((data.get('sql')! as string).includes('WHERE') == true) { + Log.i(TAG, "鸿蒙 开始查询数据"); + let tableName: string = SqlHelper.getQuerySqlTableName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 查询数据获取表名 :" + tableName); + let queryWhere: string[] = SqlHelper.getQuerySqlWhereName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 查询数据获取查询数据 :" + queryWhere); + // let querySELECT: string[] = SqfLiteHelper.getQuerySqlSELECTName(data.get('sql')! as string); + // Log.i(TAG, "鸿蒙 查询数据获取查询咧 :" + querySELECT); + let txt: string = (data.get('arguments')! as string); + // let list: string[] = txt.split(","); + // todo 这里的数据需要使用flutter传过来的才行 + let list: ValueType[] = [2]; + Log.i(TAG, "鸿蒙 查询数据获取查询值 :" + list.toString()); + Log.i(TAG, "鸿蒙 查询数据获取值完毕"); + Log.i(TAG, "鸿蒙 查询数据传入的数据queryWhere: " + queryWhere[0] + ", list:" + list[0]); + + // querySELECT 先不传 ,list[0] 很奇怪 + // let result = await rdb.query(predicates, querySELECT); + let result = await SqfLiteHelper.readOneData(dbName, tableName, queryWhere[0], list[0]); + if (result == null) return returnMap; + let rowsData: Object[] = []; + + result.forEach((value, key) => { + let row: Object[] = []; + value.forEach((v, k) => { + row.push(v); + }) + rowsData.push(row); + }) + + returnMap.set('columns', queryWhere); + returnMap.set('rows', rowsData); + Log.i(TAG, "鸿蒙 查询数据完毕"); + } else { + Log.i(TAG, "鸿蒙 开始检查表"); + const tableName = (data.get('sql')! as string).split(" FROM ")[1]; + Log.i(TAG, "鸿蒙 检查表, 表名 :" + tableName, '%{public}s'); + let result = await SqfLiteHelper.checkTable(dbName, tableName); + returnMap.set('checkTable', result); + } + return returnMap; + } + + /// 更新数据 + async update(data: Map): Promise { + Log.i(TAG, "鸿蒙 开始修改数据"); + let rowId: number = -1; + if ((data.get('sql') as string).includes('UPDATE')) { + let dbName: string = SqfLiteHelper.dBIdList.get(data.get('id')! as number) ?? ''; + Log.i(TAG, "鸿蒙 更新数据获取数据库名:" + dbName); + let tableName: string = SqlHelper.getUpdateSqlTableName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 更新数据获取表名:" + tableName); + let queryWhere: string[] = SqlHelper.getUpdateSqlWhereName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 更新数据获取where:" + queryWhere); + let querySET: string[] = SqlHelper.getUpdateSqlSETName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 更新数据获取列:" + querySET); + + let txt: string = (data.get('arguments')! as string); + // let list: string[] = txt.split(","); + // todo 这里的数据需要使用flutter传过来的才行 + let list: ValueType[] = ['hello', 2023, 2]; + Log.i(TAG, "鸿蒙 修改数据获取到的值:" + list.toString()); + const valuesBucket: relationalStore.ValuesBucket = {} + querySET.forEach((value, index) => { + valuesBucket[value] = list[index]; + }) + + /// todo where的参数在list的后面, 要根据那个where输入的长度来动态获取 + rowId = await SqfLiteHelper.updateData(dbName, tableName, queryWhere[0], list[list.length-1], valuesBucket); + Log.i(TAG, "鸿蒙 修改数据成功的行id:" + rowId); + } else { + rowId = await this.delete(data); + Log.i(TAG, "鸿蒙 删除数据成功的行id:" + rowId); + } + return rowId; + } + + /// 删除数据 + async delete(data: Map): Promise { + let rowId: number = -1; + + let dbName: string = SqfLiteHelper.dBIdList.get(data.get('id')! as number) ?? ''; + Log.i(TAG, "鸿蒙 删除数据获取数据库名:" + dbName); + let tableName: string = SqlHelper.getDeleteSqlTableName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 删除数据获取表名:" + tableName); + let queryWhere: string[] = SqlHelper.getDeleteSqlWhereName(data.get('sql')! as string); + Log.i(TAG, "鸿蒙 删除数据获取where:" + queryWhere); + + let txt: string = (data.get('arguments')! as string); + // let list: string[] = txt.split(","); + // todo 这里的数据需要使用flutter传过来的才行 + let list: ValueType[] = [2]; + Log.i(TAG, "鸿蒙 删除数据获取值:" + list.toString()); + rowId = await SqfLiteHelper.deleteData(dbName, tableName, queryWhere[0], list[0]); + + return rowId; + } + + /// 关闭一个数据库 + async closeDatabase(dataBaseName: string): Promise { + SqfLiteHelper.closeDataBase(dataBaseName); + Log.i(TAG, "鸿蒙 关闭数据库成功"); + } + + /// 删除数据库 + async deleteDatabase(dataBaseName: string): Promise { + let result = await SqfLiteHelper.deleteDataBase(this.context!, dataBaseName); + Log.i(TAG, "鸿蒙 删除数据库成功"); + return result; + } + + /// 执行sql语句 + async execute(data: Map): Promise { + let dbName: string = SqfLiteHelper.dBIdList.get(data.get('id')! as number) ?? ''; + await SqfLiteHelper.execute(dbName, data.get('sql')! as string); + Log.i(TAG, "鸿蒙 执行sql语句成功"); + } + + /// 检查数据库是否存在 + async databaseExists(dataBaseName: string): Promise { + let result: boolean = SqfLiteHelper.databaseExists(dataBaseName); + Log.i(TAG, "鸿蒙 查询数据库是否存在成功, 结果:" + result.toString()); + return result; + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sqflite_helper.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sqflite_helper.ets new file mode 100644 index 0000000000000000000000000000000000000000..4adb8e32c1770d25d21323ae9dbf9eb5959f2c23 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sqflite_helper.ets @@ -0,0 +1,336 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; +import relationalStore from '@ohos.data.relationalStore'; +import common from '@ohos.app.ability.common'; + +const TAG: string = "SqfLiteHelper"; + +export class SqfLiteHelper { + /// 已加载的数据库 + public static dataBaseList: Map = new Map(); + /// 加载的数据库的list + public static dBIdList: Map = new Map(); + /// 加载的数据库的list + private static databaseId: number = 0; + + /// 创建一个数据库 + public static async getDataBase(context: common.Context, dataBaseName: string): Promise { + let id: number = -1; + // 从已有的数据库里面获取 + let local: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (local != null) { + SqfLiteHelper.dBIdList.forEach((value, key) => { + if (dataBaseName == value) { + id = key; + } + }) + return id; + } + + // 从系统中获取 + const config: relationalStore.StoreConfig = { + name: dataBaseName + '.db', // 数据库文件名 + securityLevel: relationalStore.SecurityLevel.S1 // 数据库安全级别 + }; + + try { + let rdbStore = await relationalStore.getRdbStore(context, config); + Log.i(TAG, '创建数据库 ' + dataBaseName + ' 正常', '%{public}s'); + SqfLiteHelper.dataBaseList.set(dataBaseName, rdbStore); + id = SqfLiteHelper.databaseId + 1; + SqfLiteHelper.dBIdList.set(id, dataBaseName); + } catch (err) { + Log.i(TAG, '创建数据库出现异常: ' + err, '%{public}s'); + } + return id; + } + + /// 从已加载的列表里获取一个数据库 + private static getOnlyLocal(dataBaseName: string): relationalStore.RdbStore | null { + if (SqfLiteHelper.dataBaseList.has(dataBaseName)) { + return SqfLiteHelper.dataBaseList.get(dataBaseName) as relationalStore.RdbStore | null; + } + Log.i(TAG, '没有加载这个数据库', '%{public}s'); + return null; + } + + /// 关闭一个数据库 + public static closeDataBase(dataBaseName: string): void { + if (SqfLiteHelper.dataBaseList.has(dataBaseName)) { + SqfLiteHelper.dataBaseList.delete(dataBaseName); + let id: number = -1; + SqfLiteHelper.dBIdList.forEach((value, key) => { + if (dataBaseName == value) { + id = key; + } + }) + if (id > -1) { + SqfLiteHelper.dBIdList.delete(id); + Log.i(TAG, '已关闭 ' + dataBaseName + ' 数据库', '%{public}s'); + return; + } + } + Log.i(TAG, '没有找到该数据库无法关闭', '%{public}s'); + } + + /// 删除一个数据库 + public static async deleteDataBase(context: common.Context, dataBaseName: string): Promise { + let result: boolean = false; + if (SqfLiteHelper.dataBaseList.has(dataBaseName)) { + Log.i(TAG, '已加载数据库, 尝试删除', '%{public}s'); + SqfLiteHelper.dataBaseList.delete(dataBaseName); + let id: number = -1; + SqfLiteHelper.dBIdList.forEach((value, key) => { + if (dataBaseName == value) { + id = key; + } + }) + if (id > -1) { + SqfLiteHelper.dBIdList.delete(id); + await relationalStore.deleteRdbStore(context, dataBaseName); + Log.i(TAG, '已删除 ' + dataBaseName + ' 数据库', '%{public}s'); + result = true; + } + } else { + Log.i(TAG, '未加载数据库, 尝试删除', '%{public}s'); + try { + // todo 这里需要注意一下 + if (await SqfLiteHelper.checkTable(dataBaseName, 'defaultTable') == true) { + await SqfLiteHelper.deleteTable(dataBaseName, 'defaultTable'); + } + await relationalStore.deleteRdbStore(context, dataBaseName); + Log.i(TAG, '已删除 ' + dataBaseName + ' 数据库', '%{public}s'); + result = true; + } catch (e) { + Log.i(TAG, '删除数据库出错', '%{public}s'); + } + } + + Log.i(TAG, '没有找到该数据库无法删除', '%{public}s'); + return result; + } + + /// 检查数据库 + public static databaseExists(dataBaseName: string): boolean { + // let sql: string = "SHOW DATABASES LIKE " + dataBaseName; + // + // let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + // if (dataBase == null) return success; + + // todo 这里还没有实现 + return true; + } + + /// 检查表 + public static async checkTable(dataBaseName: string, tableName: string): Promise { + let success: boolean = false; + + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return success; + try { + let predicates = new relationalStore.RdbPredicates(tableName); + predicates.isNull('id'); + let result = await dataBase.query(predicates); + if (result.columnCount > 0) { + Log.i(TAG, '检查表' + tableName + '已存在', '%{public}s'); + success = true; + } else { + Log.i(TAG, '检查表' + tableName + '不存在', '%{public}s'); + } + } catch (e) { + Log.i(TAG, '检查表' + tableName + '出现异常: ' + e, '%{public}s'); + } + + return success; + } + + /// 创建表 + public static async createTable(dataBaseName: string, tableName: string, data: string = ''): Promise { + let success: boolean = false; + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return success; + + try { + await dataBase.executeSql('CREATE TABLE IF NOT EXISTS ' + tableName + '(' + data + ')') + Log.i(TAG, '创建表' + tableName + '成功', '%{public}s'); + success = true; + } catch (e) { + Log.i(TAG, '创建表' + tableName + '出现异常: ' + e, '%{public}s'); + } + return success; + } + + /// 删除表 + public static async deleteTable(dataBaseName: string, tableName: string): Promise { + let success: boolean = false; + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return success; + let checkTableSql = 'DROP TABLE ' + tableName; + try { + await dataBase.executeSql(checkTableSql); + Log.i(TAG, '删除表' + tableName + '成功', '%{public}s'); + success = true; + } catch (e) { + Log.i(TAG, '删除表' + tableName + '出现异常: ' + e, '%{public}s'); + } + return success; + } + + /// 插入一条数据 + public static async insertData(dataBaseName: string, tableName: string, valuesBucket: relationalStore.ValuesBucket): Promise { + let rowId: number = -1; + + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return rowId; + + try { + rowId = await dataBase.insert(tableName, valuesBucket); + if (rowId >= 0) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表插入数据成功, 行id: ' + rowId, '%{public}s'); + } else { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表插入数据返回值不正常: ' + rowId, '%{public}s'); + } + } catch (e) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表插入数据出现异常: ' + e.code + '---' + e.message, '%{public}s'); + } + return rowId; + } + + /// 读取一条数据 + /// [columns] 查询的咧 + /// [queryColumnName] 对应的列的名称 + /// [queryColumnData] 对应的列的值 + public static async readOneData(dataBaseName: string, tableName: string, queryColumnName: string, queryColumnData: relationalStore.ValueType, columns: Array = []): Promise> | null> { + let maps: Map> = new Map>(); + try { + Log.i(TAG, "新的>查询数据执行readOneData"); + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return null; + let predicates = new relationalStore.RdbPredicates(tableName); + predicates.equalTo(queryColumnName, queryColumnData); + + let resultSet = await dataBase.query(predicates, columns); + Log.i(TAG, "新的>鸿蒙查询数据成功"); + while (resultSet.goToNextRow()) { + let map: Map = new Map(); + for (let i = 0; i < resultSet.columnCount; i++) { + let key = resultSet.getColumnName(i); + let value = resultSet.getString(i); + map.set(key, value); + } + Log.i(TAG, '取出的值 -> ' + map, '%{public}s'); + maps.set(maps.size.toString(), map); + } + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表读取数据成功: ', '%{public}s'); + return maps; + } catch (e) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表读取数据出现异常: ' + e.code + '---' + e.message, '%{public}s'); + } + return null; + } + + /// 更新一条数据 + public static async updateData(dataBaseName: string, tableName: string, queryColumnName: string, queryColumnData: relationalStore.ValueType, valuesBucket: relationalStore.ValuesBucket): Promise { + let rowId: number = 0; + try { + Log.i(TAG, "新的>更新数据执行updateData"); + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return rowId; + + let predicates = new relationalStore.RdbPredicates(tableName); + predicates.equalTo(queryColumnName, queryColumnData); + + rowId = await dataBase.update(valuesBucket, predicates); + Log.i(TAG, "新的>鸿蒙更新数据成功"); + if (rowId > 0) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表更新数据成功, 影响行数: ' + rowId, '%{public}s'); + } else { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表更新数据成功, 返回值不正常: ' + rowId, '%{public}s'); + } + } catch (e) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表更新数据出现异常: ' + e.code + '---' + e.message, '%{public}s'); + } + return rowId; + } + + /// 删除一条数据 + public static async deleteData(dataBaseName: string, tableName: string, queryColumnName: string, queryColumnData: relationalStore.ValueType): Promise { + let rowId: number = -1; + + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return rowId; + + try { + let predicates = new relationalStore.RdbPredicates(tableName); + predicates.equalTo(queryColumnName, queryColumnData); + rowId = await dataBase.delete(predicates); + if (rowId >= 0) { + // todo 这里删除0行暂时视为成功 + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表删除数据成功, 影响行数: ' + rowId, '%{public}s'); + } else { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表删除数据失败, 影响行数: ' + rowId, '%{public}s'); + } + } catch (err) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表删除数据出现异常: ' + err.message, '%{public}s'); + } + return rowId; + } + + + /// 执行一个sql语句 + public static async execute(dataBaseName: string, sql: string): Promise { + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return; + await dataBase.executeSql(sql); + } + + /// 为一个表添加一个新的属性 + public static async addNewProperty(dataBaseName: string, tableName: string, propertyName: string): Promise { + let success: boolean = false; + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return false; + + try { + await dataBase.executeSql('ALTER TABLE ' + tableName + ' ADD ' + propertyName); + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表添加属性成功', '%{public}s'); + success = true; + } catch (err) { + Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表添加属性出现异常: ' + err.message, '%{public}s'); + } + return success; + } + + /// 为一个表删除一个的属性 + public static async deleteProperty(dataBaseName: string, tableName: string, propertyName: string): Promise { + let success: boolean = false; + let dataBase: relationalStore.RdbStore | null = SqfLiteHelper.getOnlyLocal(dataBaseName); + if (dataBase == null) return false; + + try { + await dataBase.executeSql('ALTER TABLE ' + tableName + ' DROP COLUMN ' + propertyName); + success = true; + // Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表删除属性成功', '%{public}s'); + } catch (err) { + // Log.i(TAG, dataBaseName + ' 的 ' + tableName + ' 表删除属性出现异常: ' + err.message, '%{public}s'); + } + return success; + } +} + + + + diff --git a/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sql_helper.ets b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sql_helper.ets new file mode 100644 index 0000000000000000000000000000000000000000..c3382db680664d0bf4d429855187fa3fdf3f2452 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/ets/sqflite/sql_helper.ets @@ -0,0 +1,201 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +export class SqlHelper { + /// 分离sql的属性部分 + public static getSqlDataName(jsonStr: string): string[] { + // 提取属性部分 + let pattern = new RegExp('INSERT INTO (\\w+) \\(([^()]+)\\)'); + const propertiesMatch = pattern.exec(jsonStr); + const propertiesStr = propertiesMatch ? propertiesMatch[2] : ''; // 提取属性部分的字符串 + const properties = propertiesStr.split(',').map(prop => prop.trim()); // 将属性部分字符串拆分为数组 + return properties; + } + + /// 分离sql的值部分 + public static getSqlData(jsonStr: string): string[] { + // 提取值部分 + const valuesRegex = '/VALUES \(([^)]+)\)/'; // 匹配VALUES括号内的值部分 + const valuesMatch = jsonStr.match(valuesRegex); + const valuesStr = valuesMatch ? valuesMatch[1] : ''; // 提取值部分的字符串 + const values = valuesStr.split(',') + .map(val => val.trim()) + .map(val => val.replace('/\?/g', '')); // 将值部分字符串拆分为数组,并去掉问号 + return values; + } + + /// 分离sql的表名部分 + public static getInsertSqlTableName(jsonStr: string): string { + // 提取表名 + let pattern = new RegExp('INSERT INTO (\\w+) \\(([^()]+)\\)'); + const propertiesMatch = pattern.exec(jsonStr); + const propertiesStr = propertiesMatch ? propertiesMatch[1] : ''; // 提取属性部分的字符串 + return propertiesStr; + } + + /// 分离sql的表名部分 + public static getQuerySqlTableName(jsonStr: string): string { + // 提取表名 + let pattern = new RegExp("SELECT \\* FROM (\\w+) WHERE (\\w+ = \\?)(?: AND (\\w+ = \\?))*") + let match = pattern.exec(jsonStr) + if (match == null) return ''; + return match[1]; + } + + /// 分离sql的Where部分 + public static getQuerySqlWhereName(jsonStr: string): string[] { + + // 提取表名 + let pattern = new RegExp("SELECT \\* FROM (\\w+) WHERE (\\w+ = \\?)(?: AND (\\w+ = \\?))*") + let match = pattern.exec(jsonStr) + if (match == null) return []; + const whereClauses: string[] = match.slice(2).filter((clause: string) => clause !== undefined); + + const whereColumns: string[] = whereClauses.filter((clause) => clause.includes('=')) + .map((clause) => clause.split('=')[0].trim()); + return whereColumns; + } + + /// 分离sql的SELECT部分 + public static getQuerySqlSELECTName(jsonStr: string): string[] { + // 提取SELECT后面的参数 + const selectParamsRegex = '/SELECT\s+([^\s]+)\s+FROM/'; // 正则表达式匹配SELECT和FROM之间的参数 + const selectParamsMatch = jsonStr.match(selectParamsRegex); + const selectParams = selectParamsMatch ? selectParamsMatch[1].split(',') : []; // 将参数按逗号分隔成数组 + return selectParams; + } + + /// 分离sql的表名部分 + public static getUpdateSqlTableName(jsonStr: string): string { + let pattern = new RegExp("UPDATE (\\w+)"); + let match = pattern.exec(jsonStr); + if (match == null) return ''; + return match[1]; + } + + /// 分离sql的Where部分 + public static getUpdateSqlWhereName(jsonStr: string): string[] { + // 提取WHERE后面的参数 + const wherePattern: RegExp = new RegExp('WHERE\\s+([^]+?)\\s*$'); // 匹配WHERE后面的值 + const whereMatch = jsonStr.match(wherePattern); + if (whereMatch == null) return []; + const whereValues = whereMatch[1].split(',').map((clause) => clause.split('=')[0].trim()); + return whereValues; + } + + /// 分离sql的SELECT部分 + public static getUpdateSqlSETName(jsonStr: string): string[] { + // 提取SET后面的参数 + const setPattern: RegExp = new RegExp('SET +([^]+?) +WHERE'); // 匹配SET后面的值 + const setMatch = jsonStr.match(setPattern); + if (setMatch == null) return []; + const setValues = setMatch[1].split(',').map((clause) => clause.split('=')[0].trim()); + return setValues; + } + + /// 分离sql的表名部分 + public static getDeleteSqlTableName(jsonStr: string): string { + // 提取表名 + let pattern = new RegExp("DELETE FROM (\\w+)"); + let match = pattern.exec(jsonStr); + if (match == null) return ''; + return match[1]; + } + + /// 分离sql的Where部分 + public static getDeleteSqlWhereName(jsonStr: string): string[] { + // 提取WHERE后面的参数 + const wherePattern: RegExp = new RegExp('WHERE +([^]+?) *$'); // 匹配WHERE后面的值 + const whereMatch = jsonStr.match(wherePattern); + if (whereMatch == null) return []; + const whereValues = whereMatch[1].split(',').map((clause) => clause.split('=')[0].trim()); + return whereValues; + } + + /// 获取数据库路径上的最后一项作为数据库名 + public static getLastPathName(path: string): string { + // 通过split方法将路径分割成数组 + const pathParts = path.split('/'); + + // 获取最后一个元素 + return pathParts[pathParts.length - 1]; + } + + /// map转化为json + public static mapToJson(jsonStr: Map): string { + if (jsonStr.size <= 0) return '{}'; + let result: string = '{'; + jsonStr.forEach((value, key) => { + result += key + ":" + value.toString() + ","; + }) + // 可以选择去掉最后一个逗号 + // result = result.slice(0, -1); + result += '}'; + return result; + } + + // /// json转化为map + // public static parseJsonString(jsonStr: string): Map { + // // 去除字符串两端的空格 + // jsonStr = jsonStr.trim(); + // + // // 检查字符串是否以 '{' 开头和以 '}' 结尾 + // if (jsonStr[0] !== '{' || jsonStr[jsonStr.length - 1] !== '}') { + // throw new Error('Invalid JSON string format'); + // } + // + // // 创建一个空的Map对象 + // const map = new Map(); + // + // // 去除首尾的 {} 后,将字符串按 ',' 分割为键值对数组 + // const keyValuePairs = jsonStr.slice(1, -1).split(','); + // + // // 遍历键值对数组 + // for (const keyValuePair of keyValuePairs) { + // // 使用 ':' 分割键和值 + // const list: Array = keyValuePair.split(':'); + // + // // 去除键和值两端的空格 + // // const trimmedKey = list[0].trim(); + // // const trimmedValue = list[1].trim(); + // + // // 将键和值添加到Map中 + // if (list[0] != '') { + // map.set(list[0], list[1]); + // } + // } + // return map; + // } + + /// 获取map的keys + // public static getMapKeys(jsonStr: Map): string { + // let result: string = ''; + // jsonStr.forEach((value, key) => { + // result += key + ', '; + // }) + // result = result.slice(0, result.length - 2); + // return result; + // } + + /// 获取map的values + // public static getMapValues(jsonStr: Map): string { + // let result: string = ''; + // jsonStr.forEach((value, key) => { + // result += value + ', '; + // }) + // result = result.slice(0, result.length - 2); + // return result; + // } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/module.json5 b/ohos/test_sqflite/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_sqflite/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_sqflite/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_sqflite/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..03eaddffb9c0e55fb7b5f9b378d9134d8d75dd37 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{"packages/cupertino_icons/assets/CupertinoIcons.ttf":["packages/cupertino_icons/assets/CupertinoIcons.ttf"]} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..464ab5882a2234c39b1a4dbad5feba0954478155 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]},{"family":"packages/cupertino_icons/CupertinoIcons","fonts":[{"asset":"packages/cupertino_icons/assets/CupertinoIcons.ttf"}]}] \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..e964eaaa5922ee7b69c5fff2e09e704ef3a64133 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..e3f7b2abdf8d372e906ccd6463a8eb56c3e52ddd Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf new file mode 100644 index 0000000000000000000000000000000000000000..79ba7ea0836b93b3f178067bcd0a0945dbc26b3f Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/packages/cupertino_icons/assets/CupertinoIcons.ttf differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_sqflite/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_sqflite/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_sqflite/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_sqflite/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/har/flutter_embedding.har b/ohos/test_sqflite/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_sqflite/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_sqflite/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.10 b/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.9 b/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_sqflite/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_sqflite/ohos/har/libflutter.so.debug.10 b/ohos/test_sqflite/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_sqflite/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_sqflite/ohos/har/libflutter.so.release.10 b/ohos/test_sqflite/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_sqflite/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_sqflite/ohos/hvigor/hvigor-config.json5 b/ohos/test_sqflite/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_sqflite/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_sqflite/ohos/hvigor/hvigor-wrapper.js b/ohos/test_sqflite/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_sqflite/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/hvigorfile.ts b/ohos/test_sqflite/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_sqflite/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/hvigorw b/ohos/test_sqflite/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_sqflite/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_sqflite/ohos/hvigorw.bat b/ohos/test_sqflite/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_sqflite/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_sqflite/ohos/oh-package-lock.json5 b/ohos/test_sqflite/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_sqflite/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_sqflite/ohos/oh-package.json5 b/ohos/test_sqflite/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_sqflite/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_sqflite/pubspec.yaml b/ohos/test_sqflite/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..2daa29ee5548b76f99b96b0f212680de44792e64 --- /dev/null +++ b/ohos/test_sqflite/pubspec.yaml @@ -0,0 +1,41 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_sqflite +description: A new Flutter project. +publish_to: none + +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^1.0.2 + path: '>=1.8.0 <3.0.0' +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^2.0.0 +flutter: + uses-material-design: true +dependency_overrides: + sqflite: + path: ./lib/sqflite +# sqflite_ohos: +# path: ./lib/sqflite_ohos + diff --git a/ohos/test_sqflite_common/.gitignore b/ohos/test_sqflite_common/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_sqflite_common/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_sqflite_common/.metadata b/ohos/test_sqflite_common/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_sqflite_common/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_sqflite_common/README.md b/ohos/test_sqflite_common/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_sqflite_common/analysis_options.yaml b/ohos/test_sqflite_common/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_sqflite_common/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_sqflite_common/lib/common/base_page.dart b/ohos/test_sqflite_common/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_sqflite_common/lib/common/item_widget.dart b/ohos/test_sqflite_common/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_sqflite_common/lib/common/main_item_widget.dart b/ohos/test_sqflite_common/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_sqflite_common/lib/common/test_model_app.dart b/ohos/test_sqflite_common/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_sqflite_common/lib/common/test_page.dart b/ohos/test_sqflite_common/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_sqflite_common/lib/common/test_route.dart b/ohos/test_sqflite_common/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_sqflite_common/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_sqflite_common/lib/main.dart b/ohos/test_sqflite_common/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..70a96d155c1323f10da1f0dabd333cb78be307e9 --- /dev/null +++ b/ohos/test_sqflite_common/lib/main.dart @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_sqflite_common/src/import_mixin_test.dart'; +import 'package:test_sqflite_common/src/list_mixin_test.dart'; +import 'package:test_sqflite_common/src/path_utils_test.dart'; +import 'package:test_sqflite_common/src/sqflite_batch_test.dart'; +import 'package:test_sqflite_common/src/sqflite_debug_test.dart'; +import 'package:test_sqflite_common/src/sqflite_dev_test.dart'; +import 'package:test_sqflite_common/src/sqflite_exception_test.dart'; +import 'package:test_sqflite_common/src/sqflite_impl_test.dart'; +import 'package:test_sqflite_common/src/sqflite_logger_test.dart'; +import 'package:test_sqflite_common/src/sqflite_not_initialized_test.dart'; +import 'package:test_sqflite_common/src/sqflite_open_test.dart'; +import 'package:test_sqflite_common/src/sqflite_sql_test.dart'; +import 'package:test_sqflite_common/src/sqflite_transaction_test.dart'; +import 'package:test_sqflite_common/src/sql_builder_test.dart'; +import 'package:test_sqflite_common/src/sql_test.dart'; +import 'package:test_sqflite_common/src/sqlite_api_test.dart'; +import 'package:test_sqflite_common/src/src_mixin_factory_test.dart'; +import 'package:test_sqflite_common/src/src_mixin_test.dart'; +import 'package:test_sqflite_common/src/utils_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + final app = [ + MainItem('import_mixin_test', ImportMixinTestPage('import_mixin_test')), + MainItem('list_mixin_test', ListMixinTestPage('list_mixin_test')), + MainItem('path_utils_test', PathUtilsTestPage('path_utils_test')), + MainItem('sqflite_batch_test', SqfliteBatchTestPage('sqflite_batch_test')), + MainItem('sqflite_debug_test', SqfliteDebugTestPage('sqflite_debug_test')), + MainItem('sqflite_dev_test', SqfliteDevTestPage('sqflite_dev_test')), + MainItem('sqflite_exception_test', SqfliteExceptionTestPage('sqflite_exception_test')), + MainItem('sqflite_impl_test', SqfliteImplTestPage('sqflite_impl_test')), + MainItem('sqflite_logger_test', SqfliteLoggerTestPage('sqflite_logger_test')), + MainItem('sqflite_not_initialized_test', SqfliteNotInitializedTestPage('sqflite_not_initialized_test')), + MainItem('sqflite_open_test', SqfliteOpenTestPage('sqflite_open_test')), + MainItem('sqflite_sql_test', SqfliteSqlTestPage('sqflite_sql_test')), + MainItem('sqflite_transaction_test', SqfliteTransactionTestPage('sqflite_transaction_test')), + MainItem('sql_builder_test', SqlBuilderTestPage('sql_builder_test')), + MainItem('sql_test', SqlTestPage('sql_test')), + MainItem('sqlite_api_test', SqliteApiTestPage('sqlite_api_test')), + MainItem('src_mixin_factory_test', SrcMixinFactoryTestPage('src_mixin_factory_test')), + MainItem('src_mixin_test', SrcMixinTestPage('src_mixin_test')), + MainItem('utils_test', UtilsTestPage('utils_test')), + ]; + + runApp(TestModelApp(appName: 'sqflite_common', data: app)); +} diff --git a/ohos/test_sqflite_common/lib/src/import_mixin_test.dart b/ohos/test_sqflite_common/lib/src/import_mixin_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..d21b63e83236629366916e710342dbe59b1c127d --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/import_mixin_test.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/src/mixin/dev_utils.dart'; +import 'package:sqflite_common/src/mixin/import_mixin.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class ImportMixinTestPage extends TestPage { + ImportMixinTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('handler_mixin', () { + // Check that public api are exported + test('exported', () { + for (var value in [ + // ignore: deprecated_member_use_from_same_package + SqfliteOptions, + methodOpenDatabase, + methodOpenDatabase, + methodCloseDatabase, + methodOptions, + sqliteErrorCode, + methodInsert, + methodQuery, + methodUpdate, + methodExecute, + methodBatch, + // Factory + buildDatabaseFactory, SqfliteInvokeHandler, SqfliteDatabaseFactoryBase, + SqfliteDatabaseFactoryMixin, SqfliteDatabaseFactory, + // Database + SqfliteDatabaseOpenHelper, SqfliteDatabase, SqfliteDatabaseMixin, + SqfliteDatabaseBase, + // Exception + SqfliteDatabaseException, + // ignore: deprecated_member_use_from_same_package + devPrint, devWarning, + ]) { + expect(value, value !=null); + } + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/list_mixin_test.dart b/ohos/test_sqflite_common/lib/src/list_mixin_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3889a822def0f9fce628d3ec3ffb98ba10cb4e6e --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/list_mixin_test.dart @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:collection'; + +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class MyList1 extends Object with ListMixin> { + MyList1.from(this._list); + + final List _list; + + @override + Map operator [](int index) { + final value = _list[index] as Map; + return value.cast(); + } + + @override + void operator []=(int index, Map value) { + throw 'read-only'; + } + + @override + set length(int newLength) { + throw 'read-only'; + } + + @override + int get length => _list.length; +} + +class MyList2 extends ListBase> { + MyList2.from(this._list); + + final List _list; + + @override + Map operator [](int index) { + final value = _list[index] as Map; + return value.cast(); + } + + @override + void operator []=(int index, Map value) { + throw 'read-only'; + } + + @override + set length(int newLength) { + throw 'read-only'; + } + + @override + int get length => _list.length; +} +class ListMixinTestPage extends TestPage { + ListMixinTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('mixin', () { + // This fails on beta 1, should work now + test('ListMixin', () { + final raw = [ + {'col': 1} + ]; + final rows = MyList1.from(raw); + expect(rows, raw); + }); + + test('ListBase', () { + final raw = [ + {'col': 1} + ]; + final rows = MyList2.from(raw); + expect(rows, raw); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/path_utils_test.dart b/ohos/test_sqflite_common/lib/src/path_utils_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..f9ae576c3d412bb3ff2276ef15d35b5640c72046 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/path_utils_test.dart @@ -0,0 +1,39 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/path_utils.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class PathUtilsTestPage extends TestPage { + PathUtilsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('数据库路径', () { + test('在内存中的数据库', () { + expect(inMemoryDatabasePath, ':memory:'); + expect(isInMemoryDatabasePath('test.db'), false); + expect(isInMemoryDatabasePath(':memory:'), true); + expect(isInMemoryDatabasePath('file::memory:'), true); + }); + + test('文件路径', () { + expect(isFileUriDatabasePath('file::memory:'), true); + expect(isFileUriDatabasePath('filememory'), false); + expect(isFileUriDatabasePath('file:relative'), true); + expect(isFileUriDatabasePath('file:///abs'), true); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_batch_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_batch_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..348518b7a10e62a572e15bff095da7de7dc43d2a --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_batch_test.dart @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'test_scenario.dart'; +class SqfliteBatchTestPage extends TestPage { + SqfliteBatchTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('批量功能测试', () { + var startCommands = [protocolOpenStep]; + var endCommands = [protocolCloseStep]; + test('批量提交', () async { + final scenario = startScenario([ + ...startCommands, + [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + null + ], + [ + 'batch', + { + 'operations': [ + {'method': 'execute', 'sql': 'PRAGMA dummy'} + ], + 'id': 1 + }, + null + ], + [ + 'execute', + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + null + ], + ...endCommands, + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + var batch = db.batch(); + expect(batch.length, 0); + batch.execute('PRAGMA dummy'); + expect(batch.length, 1); + expect(await batch.commit(), null); // Mock return values + await db.close(); + scenario.end(); + }); + test('批量应用', () async { + final scenario = startScenario([ + ...startCommands, + [ + 'batch', + { + 'operations': [ + {'method': 'execute', 'sql': 'PRAGMA dummy'} + ], + 'id': 1 + }, + null + ], + ...endCommands, + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + var batch = db.batch(); + batch.execute('PRAGMA dummy'); + await batch.apply(); + await db.close(); + scenario.end(); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_debug_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_debug_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e4e6065ec3b781dc0588b45e55603613c65cc66e --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_debug_test.dart @@ -0,0 +1,57 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/constant.dart'; +import 'package:sqflite_common/src/method_call.dart'; +import 'package:sqflite_common/src/mixin/factory.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +var logs = []; +var databaseFactoryMock = buildDatabaseFactory( + tag: 'mock', + invokeMethod: (method, [arguments]) async { + logs.add(SqfliteMethodCall(method, arguments)); + if (method == methodGetDatabasesPath) { + return 'mock_path'; + } + }); + +class SqfliteDebugTestPage extends TestPage { + SqfliteDebugTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('简单的数据库例子', () async { + logs.clear(); + // ignore: deprecated_member_use_from_same_package + await databaseFactoryMock.debugSetLogLevel(sqfliteLogLevelVerbose); + expect(logs.map((log) => log.toMap()), [ + { + 'method': 'options', + 'arguments': {'logLevel': 2} + } + ]); + }); + test('getDatabasesPath setDatabasesPath', () async { + final oldDatabasePath = await databaseFactoryMock.getDatabasesPath(); + try { + await databaseFactoryMock.setDatabasesPath('.'); + final path = await databaseFactoryMock.getDatabasesPath(); + expect(path, '.'); + } finally { + await databaseFactoryMock.setDatabasesPath(oldDatabasePath); + } + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_dev_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_dev_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..2745599c9b8bce33656073aae7f1795c302dbf65 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_dev_test.dart @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqflite_dev.dart'; +import 'package:sqflite_common/src/constant.dart'; +import 'package:sqflite_common/src/method_call.dart'; +import 'package:sqflite_common/src/mixin/factory.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +var logs = []; +var databaseFactoryMock = buildDatabaseFactory( + tag: 'mock', + invokeMethod: (method, [arguments]) async { + logs.add(SqfliteMethodCall(method, arguments)); + if (method == methodGetDatabasesPath) { + return 'mock_path'; + } + }); +class SqfliteDevTestPage extends TestPage { + SqfliteDevTestPage(String title,{ Key? key}) : super(title: title, key: key) { + test('简单的sqflite示例', () async { + logs.clear(); + // ignore: deprecated_member_use_from_same_package + await databaseFactoryMock.setLogLevel(sqfliteLogLevelVerbose); + expect(logs.map((log) => log.toMap()), [ + { + 'method': 'options', + 'arguments': {'logLevel': 2} + } + ]); + }); + test('getDatabasesPath setDatabasesPath', () async { + final oldDatabasePath = await databaseFactoryMock.getDatabasesPath(); + try { + await databaseFactoryMock.setDatabasesPath('.'); + final path = await databaseFactoryMock.getDatabasesPath(); + expect(path, '.'); + } finally { + await databaseFactoryMock.setDatabasesPath(oldDatabasePath); + } + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_exception_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_exception_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1ce15cfcacee9199ffd8668c25f03ed7ba021f73 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_exception_test.dart @@ -0,0 +1,180 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:typed_data'; + +import 'package:sqflite_common/src/exception.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqfliteExceptionTestPage extends TestPage { + SqfliteExceptionTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite_exception', () { + test('isUniqueConstraint', () async { + // Android + var msg = 'UNIQUE constraint failed: Test.name (code 2067))'; + var exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isNoSuchTableError(), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), false); + expect(exception.isNotNullConstraintError(), false); + expect(exception.isUniqueConstraintError(), true); + expect(exception.isUniqueConstraintError('Test.name'), true); + + msg = 'UNIQUE constraint failed: Test.name (code 1555))'; + exception = SqfliteDatabaseException(msg, null); + expect(exception.isSyntaxError(), false); + expect(exception.isUniqueConstraintError(), true); + expect(exception.isUniqueConstraintError('Test.name'), true); + }); + + test('isNotNullConstraint', () async { + // FFI mac + var msg = + 'DatabaseException(SqliteException(1299): NOT NULL constraint failed: Test.name, constraint failed (code 1299))'; + var exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isNoSuchTableError(), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), false); + expect(exception.isUniqueConstraintError(), false); + expect(exception.isUniqueConstraintError('Test.name'), false); + expect(exception.getResultCode(), 1299); + + // ios + msg = + 'DatabaseException(Error Domain=FMDatabase Code=1299 "NOT NULL constraint failed: Test.name"'; + exception = SqfliteDatabaseException(msg, null); + expect(exception.isSyntaxError(), false); + expect(exception.isNotNullConstraintError(), true); + expect(exception.isNotNullConstraintError('Test.name'), true); + expect(exception.isUniqueConstraintError(), false); + expect(exception.isUniqueConstraintError('Test.name'), false); + expect(exception.getResultCode(), 1299); + }); + + test('isSyntaxError', () async { + // Android + final msg = 'near "DUMMY": syntax error (code 1)'; + final exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isNoSuchTableError(), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), true); + expect(exception.isUniqueConstraintError(), false); + expect(exception.getResultCode(), 1); + }); + + test('isSyntaxError with symbolic names', () { + // Android + final msg = 'near "DUMMY": syntax error (code 1 SQLITE_ERROR)'; + final exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isNoSuchTableError(), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), true); + expect(exception.isUniqueConstraintError(), false); + expect(exception.getResultCode(), 1); + }); + + test('isNoSuchTable', () async { + // Android + final msg = 'no such table: Test (code 1)'; + final exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isNoSuchTableError(), true); + expect(exception.isNoSuchTableError('Test'), true); + expect(exception.isNoSuchTableError('Other'), false); + expect(exception.isDuplicateColumnError('tableName'), false); + expect(exception.isDuplicateColumnError(), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), false); + expect(exception.isUniqueConstraintError(), false); + expect(exception.getResultCode(), 1); + }); + + test('isDuplicateColumn', () { + // Android + final msg = 'duplicate column name: tableName (code 1 SQLITE_ERROR)'; + final exception = SqfliteDatabaseException(msg, null); + expect(exception.isDatabaseClosedError(), false); + expect(exception.isReadOnlyError(), false); + expect(exception.isDuplicateColumnError('tableName'), true); + expect(exception.isDuplicateColumnError(), true); + expect(exception.isDuplicateColumnError('tableName2'), false); + expect(exception.isNoSuchTableError(), false); + expect(exception.isNoSuchTableError('Test'), false); + expect(exception.isNoSuchTableError('Other'), false); + expect(exception.isOpenFailedError(), false); + expect(exception.isSyntaxError(), false); + expect(exception.isUniqueConstraintError(), false); + expect(exception.getResultCode(), 1); + }); + test('getResultCode', () async { + // Android + final msg = 'UNIQUE constraint failed: Test.name (code 2067))'; + var exception = SqfliteDatabaseException(msg, null); + expect(exception.getResultCode(), 2067); + exception = SqfliteDatabaseException( + 'UNIQUE constraint failed: Test.name (code 1555))', null); + expect(exception.getResultCode(), 1555); + exception = + SqfliteDatabaseException('near "DUMMY": syntax error (code 1)', null); + expect(exception.getResultCode(), 1); + + exception = SqfliteDatabaseException( + 'attempt to write a readonly database (code 8)) running Open read-only', + null); + expect(exception.getResultCode(), 8); + + // iOS: Error Domain=FMDatabase Code=19 'UNIQUE constraint failed: Test.name' UserInfo={NSLocalizedDescription=UNIQUE constraint failed: Test.name}) s + exception = SqfliteDatabaseException( + "Error Domain=FMDatabase Code=19 'UNIQUE constraint failed: Test.name' UserInfo={NSLocalizedDescription=UNIQUE constraint failed: Test.name})", + null); + expect(exception.getResultCode(), 19); + exception = + SqfliteDatabaseException('Error Domain=FMDatabase Code=19', null); + expect(exception.getResultCode(), 19); + }); + + test('Exception args', () async { + var exception = SqfliteDatabaseException('test', { + 'sql': 'statement', + 'arguments': [ + null, + 1, + 'short', + '123456789012345678901234567890123456789012345678901', + Uint8List.fromList([1, 2, 3]) + ] + }); + expect(exception.toString(), + 'DatabaseException(test) sql \'statement\' args [null, 1, short, 12345678901234567890123456789012345678901234567890..., Blob(3)]'); + }); + test('Exception result', () async { + DatabaseException exception = SqfliteDatabaseException('test', 1); + expect(exception.result, 1); + exception = SqfliteDatabaseException('test', null); + expect(exception.result, null); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_impl_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_impl_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..238de3ea566f890c6585425a2baa528717394c31 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_impl_test.dart @@ -0,0 +1,139 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/src/collection_utils.dart'; +import 'package:sqflite_common/src/exception.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqfliteImplTestPage extends TestPage { + SqfliteImplTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite', () { + test('Rows.from()', () { + final raw = [ + {'col': 1} + ]; + final rows = Rows.from(raw); + final row = rows.first; + expect(rows, raw); + expect(row, {'col': 1}); + }); + + test('fromRawOperationResult', () async { + expect(fromRawOperationResult({'result': 1}), 1); + expect( + fromRawOperationResult({ + 'result': { + 'columns': ['column'], + 'rows': [ + [1] + ] + } + }), + >[ + {'column': 1} + ]); + var exception = fromRawOperationResult({ + 'error': { + 'code': 1234, + 'message': 'hello', + 'data': {'some': 'data'} + } + }) as SqfliteDatabaseException; + expect(exception.message, 'hello'); + expect(exception.result, {'some': 'data'}); + expect(exception.getResultCode(), null); + + exception = fromRawOperationResult({ + 'error': { + 'code': 1234, + 'message': 'hello', + 'data': {'some': 'data'}, + 'resultCode': 1, + } + }) as SqfliteDatabaseException; + expect(exception.message, 'hello'); + expect(exception.result, {'some': 'data'}); + expect(exception.getResultCode(), 1); + }); + test('QueryResultSet', () { + final raw = { + 'columns': ['column'], + 'rows': [ + [1] + ] + }; + final queryResultSet = QueryResultSet([ + 'column' + ], [ + [1] + ]); + expect(queryResultSet.columnIndex('dummy'), null); + expect(queryResultSet.columnIndex('column'), 0); + final row = queryResultSet.first; + //expect(rows, raw); + expect(row, {'column': 1}); + + // read only + try { + row['column'] = 2; + fail('should have failed'); + } on UnsupportedError catch (_) {} + final map = Map.from(row); + // now can modify + map['column'] = 2; + + final queryResultSetMap = { + 'columns': ['id', 'name'], + 'rows': >[ + [1, 'item 1'], + [2, 'item 2'] + ] + }; + final expected = >[ + {'id': 1, 'name': 'item 1'}, + {'id': 2, 'name': 'item 2'} + ]; + expect(queryResultToList(queryResultSetMap), expected); + expect(queryResultToList(expected), expected); + expect(queryResultToList(raw), >[ + {'column': 1} + ]); + + expect(queryResultToList({}), []); + }); + + test('QueryResultSet.keys', () { + final queryResultSet = QueryResultSet([ + 'col', + 'col' + ], [ + [1, 2] + ]); + // last one wins... + expect(queryResultSet.columnIndex('col'), 1); + final row = queryResultSet.first; + expect(row['col'], 2); + + expect(row.length, 1); + expect(row.keys, ['col']); + expect(row.values, [2]); + expect(row, {'col': 2}); + }); + + test('lockWarning', () {}); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_logger_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_logger_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c50613199981c74c27771da3b6254003f1058e88 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_logger_test.dart @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/internals.dart'; +import 'package:sqflite_common/src/logger/sqflite_logger.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'src_mixin_test.dart'; +class SqfliteLoggerTestPage extends TestPage { + SqfliteLoggerTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite_logger', () { + test('内部调用测试, 输出部分日志', () async { + var events = []; + var lines = []; + final factory = SqfliteDatabaseFactoryLogger(MockDatabaseFactoryEmpty(), + options: SqfliteLoggerOptions( + type: SqfliteDatabaseFactoryLoggerType.invoke, + log: (event) { + event.dump( + print: (msg) { + lines.add(msg?.toString() ?? ''); + print(msg); + }, + noStopwatch: true); + events.add(event); + })); + try { + await factory.internalsInvokeMethod('test', {'some': 'param'}); + } catch (_) { + // unimplemented + } + var event = events.first as SqfliteLoggerInvokeEvent; + expect(event.method, 'test'); + expect(event.arguments, {'some': 'param'}); + expect(event.sw!.isRunning, false); + // is currently an error + // 'invoke:({method: test, arguments: {some: param}, error: UnimplementedError: test {some: param}})' + expect(lines.first, + 'invoke:({method: test, arguments: {some: param}'); + }); + test('输出所有日志', () async { + var events = []; + var lines = []; + final factory = SqfliteDatabaseFactoryLogger(MockDatabaseFactoryEmpty(), + options: SqfliteLoggerOptions( + type: SqfliteDatabaseFactoryLoggerType.all, + log: (event) { + event.dump( + print: (msg) { + lines.add(msg?.toString() ?? ''); + print(msg); + }, + noStopwatch: true); + events.add(event); + })); + var db = await factory.openDatabase(inMemoryDatabasePath); + var batch = db.batch(); + batch.rawQuery('PRAGMA user_version'); + await batch.commit(); + var event = events.first as SqfliteLoggerDatabaseOpenEvent; + expect(event.path, inMemoryDatabasePath); + expect(event.options?.readOnly, false); + expect(event.sw!.isRunning, false); + await db.close(); + expect(lines, [ + 'openDatabase:({path: :memory:, options: {readOnly: false, singleInstance: true}})', + 'execute:({db: 1, sql: BEGIN IMMEDIATE})', + 'batch:({db: 1})', + ' query({sql: PRAGMA user_version})', + 'execute:({db: 1, sql: COMMIT})', + 'closeDatabase:({db: 1})' + ]); + }); + test('batch', () async {}); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_not_initialized_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_not_initialized_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..254285bc826628c3cb40b09cf84961dfe68705f8 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_not_initialized_test.dart @@ -0,0 +1,28 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqflite.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqfliteNotInitializedTestPage extends TestPage { + SqfliteNotInitializedTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('未初始化sql时的测试', () { + test('打开一个内存上的数据库, 此处会报错', () async { + openDatabase(inMemoryDatabasePath); + }); + }); + } +} diff --git a/ohos/test_sqflite_common/lib/src/sqflite_open_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_open_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3b77a5632498019e657d4ec82400bcef85bf3433 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_open_test.dart @@ -0,0 +1,107 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:typed_data'; + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'test_scenario.dart'; + +class SqfliteOpenTestPage extends TestPage { + SqfliteOpenTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite', () { + test('读取id结果', () async { + final scenario = startScenario([ + [ + 'openDatabase', + {'path': ':memory:', 'singleInstance': false}, + 1 + ], + [ + 'closeDatabase', + {'id': 1}, + null + ], + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + await db.close(); + scenario.end(); + }); + test('读取map结果', () async { + final scenario = startScenario([ + [ + 'openDatabase', + {'path': ':memory:', 'singleInstance': false}, + {'id': 1}, + ], + [ + 'closeDatabase', + {'id': 1}, + null + ], + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + await db.close(); + scenario.end(); + }); + test('打开对应版本的数据库', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'query', + {'sql': 'PRAGMA user_version', 'id': 1}, + // ignore: inference_failure_on_collection_literal + {} + ], + [ + 'execute', + { + 'sql': 'BEGIN EXCLUSIVE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + null + ], + [ + 'query', + {'sql': 'PRAGMA user_version', 'id': 1}, + // ignore: inference_failure_on_collection_literal + {} + ], + [ + 'execute', + {'sql': 'PRAGMA user_version = 1', 'id': 1}, + null + ], + [ + 'execute', + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + null + ], + protocolCloseStep, + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath, + options: OpenDatabaseOptions(version: 1, onCreate: (db, version) {})); + await db.close(); + scenario.end(); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_sql_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_sql_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..3701339bfc6a0cf50139ef4791a74b5c9ac204e2 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_sql_test.dart @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:typed_data'; + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'test_scenario.dart'; + +class SqfliteSqlTestPage extends TestPage { + SqfliteSqlTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite', () { + test('使用sql语句打开数据库', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + {'sql': 'PRAGMA user_version = 1', 'id': 1}, + null, + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + await db.setVersion(1); + + await db.close(); + scenario.end(); + }); + test('事物测试 v2', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + {'transactionId': 1}, + ], + [ + 'execute', + { + 'sql': 'COMMIT', + 'id': 1, + 'inTransaction': false, + 'transactionId': 1 + }, + null, + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + await db.transaction((txn) async {}); + + await db.close(); + scenario.end(); + }); + + test('事物测试 v1', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + null, + ], + [ + 'execute', + { + 'sql': 'COMMIT', + 'id': 1, + 'inTransaction': false, + }, + null, + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + await db.transaction((txn) async {}); + + await db.close(); + scenario.end(); + }); + + test('自动关闭数据库', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + {'sql': 'BEGIN TRANSACTION', 'id': 1, 'inTransaction': true}, + null, + ], + [ + 'execute', + { + 'sql': 'ROLLBACK', + 'id': 1, + 'inTransaction': false, + 'transactionId': -1 + }, + null, + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + await db.execute('BEGIN TRANSACTION'); + + await db.close(); + scenario.end(); + }); + + test('手动关闭数据库', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + {'sql': 'BEGIN TRANSACTION', 'id': 1, 'inTransaction': true}, + null, + ], + [ + 'execute', + {'sql': 'ROLLBACK TRANSACTION', 'id': 1, 'inTransaction': false}, + null, + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + await db.execute('BEGIN TRANSACTION'); + await db.execute('ROLLBACK TRANSACTION'); + + await db.close(); + scenario.end(); + }); + test('插入数据', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'insert', + { + 'sql': 'INSERT INTO test (blob) VALUES (?)', + 'arguments': [ + [1, 2, 3] + ], + 'id': 1 + }, + 1 + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + expect( + await db.insert('test', { + 'blob': Uint8List.fromList([1, 2, 3]) + }), + 1); + await db.close(); + scenario.end(); + }); + + test('插入数据出错', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'insert', + { + 'sql': 'INSERT OR IGNORE INTO test (value) VALUES (?)', + 'arguments': [1], + 'id': 1 + }, + 1 + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + expect( + await db.insert('test', {'value': 1}, + conflictAlgorithm: ConflictAlgorithm.ignore), + 1); + await db.close(); + scenario.end(); + }); + + test('打开数据库时调用batch', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null, + }, + {'transactionId': 1} + ], + [ + 'batch', + { + 'operations': [ + { + 'method': 'insert', + 'sql': 'INSERT INTO test (blob) VALUES (?)', + 'arguments': [ + [1, 2, 3] + ] + } + ], + 'id': 1, + 'transactionId': 1 + }, + null + ], + [ + 'execute', + { + 'sql': 'COMMIT', + 'id': 1, + 'inTransaction': false, + 'transactionId': 1 + }, + null + ], + protocolCloseStep + ]); + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + final batch = db.batch(); + batch.insert('test', { + 'blob': Uint8List.fromList([1, 2, 3]) + }); + await batch.commit(); + await db.close(); + scenario.end(); + }); + + test('查询数据', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'query', + { + 'sql': '_', + 'id': 1, + 'cursorPageSize': 2, + }, + { + 'cursorId': 1, + 'rows': [ + // ignore: inference_failure_on_collection_literal + [{}] + ], + // ignore: inference_failure_on_collection_literal + 'columns': [] + } + ], + [ + 'queryCursorNext', + {'cursorId': 1, 'id': 1}, + { + 'cursorId': 1, + 'rows': [ + // ignore: inference_failure_on_collection_literal + [{}] + ], + // ignore: inference_failure_on_collection_literal + 'columns': [] + }, + ], + [ + 'queryCursorNext', + {'cursorId': 1, 'cancel': true, 'id': 1}, + null + ], + protocolCloseStep + ]); + var resultList = >[]; + final db = await scenario.factory.openDatabase(inMemoryDatabasePath); + var cursor = await db.rawQueryCursor( + '_', + null, + bufferSize: 2, + ); + expect(await cursor.moveNext(), true); + resultList.add(cursor.current); + expect(await cursor.moveNext(), true); + resultList.add(cursor.current); + await cursor.close(); + + // ignore: inference_failure_on_collection_literal + expect(resultList, [{}, {}]); + await db.close(); + scenario.end(); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqflite_transaction_test.dart b/ohos/test_sqflite_common/lib/src/sqflite_transaction_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..24c207843d4468e9d5ad54c0c142ff65cd6bf674 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqflite_transaction_test.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/exception.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'test_scenario.dart'; + +class SqfliteTransactionTestPage extends TestPage { + SqfliteTransactionTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('transaction', () { + final transactionBeginStep = [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + null, + ]; + final transactionBeginFailureStep = [ + 'execute', + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + SqfliteDatabaseException('failure', null), + ]; + final transactionEndStep = [ + 'execute', + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + 1 + ]; + test('DatabaseFactory.openDatabase', () async { + final scenario = startScenario([ + protocolOpenStep, + transactionBeginStep, + transactionEndStep, + transactionBeginStep, + transactionEndStep, + protocolCloseStep, + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + + await db.transaction((txn) async {}); + await db.transaction((txn) async {}); + await db.close(); + scenario.end(); + }); + test('检查Database.transaction', () async { + final scenario = startScenario([ + protocolOpenStep, + transactionBeginFailureStep, + transactionBeginStep, + transactionEndStep, + protocolCloseStep, + ]); + final factory = scenario.factory; + final db = await factory.openDatabase(inMemoryDatabasePath); + + try { + await db.transaction((txn) async {}); + fail('should fail'); + } on DatabaseException catch (_) {} + await db.transaction((txn) async {}); + await db.close(); + scenario.end(); + }); + test('打开过程中开始出错', () async { + final scenario = startScenario([ + protocolOpenStep, + [ + 'query', + {'sql': 'PRAGMA user_version', 'id': 1}, + // ignore: inference_failure_on_collection_literal + {}, + ], + [ + 'execute', + { + 'sql': 'BEGIN EXCLUSIVE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + SqfliteDatabaseException('failure', null), + ], + [ + 'execute', + { + 'sql': 'ROLLBACK', + 'id': 1, + 'transactionId': -1, + 'inTransaction': false + }, + null, + ], + protocolCloseStep, + ]); + final factory = scenario.factory; + try { + await factory.openDatabase(inMemoryDatabasePath, + options: + OpenDatabaseOptions(version: 1, onCreate: (db, version) {})); + } on DatabaseException catch (_) {} + scenario.end(); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sql_builder_test.dart b/ohos/test_sqflite_common/lib/src/sql_builder_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..71c94704b61d34720f64f166a871c8c3553b1892 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sql_builder_test.dart @@ -0,0 +1,216 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +//import 'package:test/test.dart'; +import 'package:sqflite_common/src/sql_builder.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqlBuilderTestPage extends TestPage { + SqlBuilderTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('SqlBuilder', () { + test('delete', () { + var builder = + SqlBuilder.delete('test', where: 'value = ?', whereArgs: [1]); + expect(builder.sql, 'DELETE FROM test WHERE value = ?'); + expect(builder.arguments, [1]); + + builder = SqlBuilder.delete('test'); + expect(builder.sql, 'DELETE FROM test'); + expect(builder.arguments, null); + + // escape + builder = SqlBuilder.delete('table'); + expect(builder.sql, 'DELETE FROM "table"'); + expect(builder.arguments, null); + }); + + test('query', () { + var builder = SqlBuilder.query('test'); + expect(builder.sql, 'SELECT * FROM test'); + expect(builder.arguments, null); + + builder = SqlBuilder.query('test', columns: ['COUNT(*)']); + expect(builder.sql, 'SELECT COUNT(*) FROM test'); + expect(builder.arguments, null); + + builder = SqlBuilder.query('test', + distinct: true, + columns: ['value'], + where: 'value = ?', + whereArgs: [1], + groupBy: 'group_value', + having: 'value > 0', + orderBy: 'other_value', + limit: 2, + offset: 3); + expect(builder.sql, + 'SELECT DISTINCT value FROM test WHERE value = ? GROUP BY group_value HAVING value > 0 ORDER BY other_value LIMIT 2 OFFSET 3'); + expect(builder.arguments, [1]); + + // no offset + builder = SqlBuilder.query('test', limit: 99); + expect(builder.sql, 'SELECT * FROM test LIMIT 99'); + expect(builder.arguments, null); + + // no limit + builder = SqlBuilder.query('test', offset: 99); + expect(builder.sql, 'SELECT * FROM test LIMIT -1 OFFSET 99'); + expect(builder.arguments, null); + }); + + test('insert', () { + try { + SqlBuilder.insert('test', {}); + fail('should fail, no nullColumnHack'); + } on ArgumentError catch (_) {} + + var builder = SqlBuilder.insert('test', {}, + nullColumnHack: 'value'); + expect(builder.sql, 'INSERT INTO test (value) VALUES (NULL)'); + expect(builder.arguments, null); + + builder = SqlBuilder.insert('test', {'value': 1}); + expect(builder.sql, 'INSERT INTO test (value) VALUES (?)'); + expect(builder.arguments, [1]); + + builder = SqlBuilder.insert( + 'test', {'value': 1, 'other_value': null}); + expect(builder.sql, + 'INSERT INTO test (value, other_value) VALUES (?, NULL)'); + expect(builder.arguments, [1]); + + builder = SqlBuilder.insert('test', {'value': 1}, + conflictAlgorithm: ConflictAlgorithm.ignore); + expect(builder.sql, 'INSERT OR IGNORE INTO test (value) VALUES (?)'); + expect(builder.arguments, [1]); + + // no escape yet + builder = SqlBuilder.insert('test', {'value:': 1}); + expect(builder.sql, 'INSERT INTO test (value:) VALUES (?)'); + expect(builder.arguments, [1]); + + // escape + builder = SqlBuilder.insert('table', {'table': 1}); + expect(builder.sql, 'INSERT INTO "table" ("table") VALUES (?)'); + expect(builder.arguments, [1]); + }); + + test('update', () { + try { + SqlBuilder.update('test', {}); + fail('should fail, no values'); + } on ArgumentError catch (_) {} + + var builder = SqlBuilder.update('test', {'value': 1}); + expect(builder.sql, 'UPDATE test SET value = ?'); + expect(builder.arguments, [1]); + + builder = SqlBuilder.update( + 'test', {'value': 1, 'other_value': null}); + expect(builder.sql, 'UPDATE test SET value = ?, other_value = NULL'); + expect(builder.arguments, [1]); + + // testing where + builder = SqlBuilder.update('test', {'value': 1}, + where: 'a = ? AND b = ?', whereArgs: ['some_test', 1]); + expect(builder.arguments, [1, 'some_test', 1]); + + // no escape yet + builder = SqlBuilder.update('test:', {'value:': 1}); + expect(builder.sql, 'UPDATE test: SET value: = ?'); + expect(builder.arguments, [1]); + + // escape + builder = SqlBuilder.update('test:', {'table': 1}); + expect(builder.sql, 'UPDATE test: SET "table" = ?'); + expect(builder.arguments, [1]); + }); + + test('query', () { + var builder = SqlBuilder.query('table', orderBy: 'value'); + expect(builder.sql, 'SELECT * FROM "table" ORDER BY value'); + expect(builder.arguments, null); + + builder = + SqlBuilder.query('table', orderBy: 'column_1 ASC, column_2 DESC'); + expect(builder.sql, + 'SELECT * FROM "table" ORDER BY column_1 ASC, column_2 DESC'); + expect(builder.arguments, null); + + // testing where + builder = SqlBuilder.query('test', + where: 'a = ? AND b = ?', whereArgs: ['some_test', 1]); + expect(builder.arguments, ['some_test', 1]); + }); + + test('isEscapedName', () { + //expect(isEscapedName(null), false); + expect(isEscapedName('group'), false); + expect(isEscapedName("'group'"), false); + expect(isEscapedName('"group"'), true); + expect(isEscapedName('`group`'), true); + expect(isEscapedName("`group'"), false); + expect(isEscapedName('"group"'), true); + }); + + test('escapeName', () { + // expect(escapeName(null!), null); + expect(escapeName('group'), '"group"'); + expect(escapeName('dummy'), 'dummy'); + expect(escapeName('"dummy"'), '"dummy"'); + expect(escapeName('semicolumn:'), 'semicolumn:'); // for now no escape + expect( + escapeName( + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'), + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'); + + for (var name in escapeNames) { + expect(escapeName(name), '"$name"'); + } + }); + + test('escapeEntityName', () { + // expect(escapeEntityName(null!), null); + expect(escapeEntityName('group'), '"group"'); + expect(escapeEntityName('dummy'), 'dummy'); + expect(escapeEntityName('"dummy"'), '""dummy""'); + expect(escapeEntityName('semicolumn:'), '"semicolumn:"'); + expect( + escapeEntityName( + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'), + 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_0123456789'); + + for (var name in escapeNames) { + expect(escapeEntityName(name), '"$name"'); + } + }); + + test('unescapeName', () { + // expect(unescapeName(null!), null); + + expect(unescapeName('dummy'), 'dummy'); + expect(unescapeName("'dummy'"), "'dummy'"); + expect(unescapeName("'group'"), "'group'"); + expect(unescapeName('"group"'), 'group'); + expect(unescapeName('`group`'), 'group'); + + for (var name in escapeNames) { + expect(unescapeName('"$name"'), name); + } + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sql_test.dart b/ohos/test_sqflite_common/lib/src/sql_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..15cd2c755dc38559fc3dd9c9a94072bd3b7d7ec0 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sql_test.dart @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sql.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqlTestPage extends TestPage { + SqlTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite', () { + test('ConflictAlgorithm 枚举调用是否正常', () { + expect(ConflictAlgorithm.abort, null); + }); + + test('escapeName', () { + expect(escapeName('group'), '"group"'); + }); + + test('unescapeName', () { + expect(unescapeName('"group"'), 'group'); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/sqlite_api_test.dart b/ohos/test_sqflite_common/lib/src/sqlite_api_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c346a11ac5d2df7bb282d8cc8a284c5344aba155 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/sqlite_api_test.dart @@ -0,0 +1,47 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SqliteApiTestPage extends TestPage { + SqliteApiTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqlite_api', () { + // Check that public api are exported + test('接口暴露检查', () { + for (var value in [ + OpenDatabaseOptions, + DatabaseFactory, + Database, + Transaction, + Batch, + ConflictAlgorithm, + inMemoryDatabasePath, + OnDatabaseConfigureFn, + OnDatabaseCreateFn, + OnDatabaseOpenFn, + OnDatabaseVersionChangeFn, + onDatabaseDowngradeDelete, + sqfliteLogLevelNone, + sqfliteLogLevelSql, + sqfliteLogLevelVerbose, + ]) { + expect(value, null); + } + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/src_mixin_factory_test.dart b/ohos/test_sqflite_common/lib/src/src_mixin_factory_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..bff357f295e377828c20a0cab625355edae1281a --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/src_mixin_factory_test.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/constant.dart'; +import 'package:sqflite_common/src/factory_mixin.dart'; +import 'package:sqflite_common/src/mixin/factory.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'src_mixin_test.dart'; + +class SrcMixinFactoryTestPage extends TestPage { +SrcMixinFactoryTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('mixin_factory', () { + test('buildDatabaseFactory', () { + // ignore: unnecessary_statements + buildDatabaseFactory; + // ignore: unnecessary_statements + SqfliteInvokeHandler; + }); + test('buildDatabaseFactory', () async { + final methods = []; + final factory = buildDatabaseFactory( + tag: 'mock', + invokeMethod: (String method, [Object? arguments]) async { + final dynamic result = mockResult(method, arguments); + methods.add(method); + return result; + }); + expect((factory as SqfliteDatabaseFactoryMixin).tag, 'mock'); + // ignore: unnecessary_type_check + expect(factory is SqfliteInvokeHandler, true); + await factory.openDatabase(inMemoryDatabasePath); + expect(methods, ['openDatabase']); + }); + }); +} +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/lib/src/src_mixin_test.dart b/ohos/test_sqflite_common/lib/src/src_mixin_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c8fa7c3d425440871769858544b36686bede9bd5 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/src_mixin_test.dart @@ -0,0 +1,818 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:path/path.dart'; +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/constant.dart'; +import 'package:sqflite_common/src/database.dart'; +import 'package:sqflite_common/src/mixin.dart'; +import 'package:sqflite_common/src/mixin/dev_utils.dart'; // ignore: unused_import +import 'package:sqflite_common/src/open_options.dart'; +import 'package:sqflite_common/utils/utils.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +var _mockDatabasesPath = '.'; + +/// Mock the result based on the method used +Object? mockResult(String method, Object? arguments) { + Object? handleSqlMethod(String sqlMethod) { + switch (sqlMethod) { + case methodOpenDatabase: + return 1; + case methodInsert: + return 0; + case methodUpdate: + return 0; + case methodExecute: + return null; + case methodQuery: + return {}; + } + throw UnimplementedError('$method $sqlMethod $arguments'); + } + + // devPrint('$method'); + switch (method) { + case methodGetDatabasesPath: + return _mockDatabasesPath; + case methodOpenDatabase: + return 1; + case methodCloseDatabase: + return null; + case methodDeleteDatabase: + return null; + case methodDatabaseExists: + return true; + case methodInsert: + case methodUpdate: + case methodExecute: + case methodQuery: + return handleSqlMethod(method); + case methodBatch: + var operations = (arguments as Map)[paramOperations] as List; + var results = []; + for (var operation in operations) { + var sqlMethod = (operation as Map)[paramMethod] as String; + results.add(handleSqlMethod(sqlMethod)); + } + return results; + } + throw UnimplementedError('$method $arguments'); +} + +class MockDatabase extends SqfliteDatabaseBase { + MockDatabase(SqfliteDatabaseOpenHelper openHelper, [String name = 'mock']) + : super(openHelper, name); + + int? version; + List methods = []; + List sqls = []; + List?> argumentsLists = ?>[]; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + // return super.invokeMethod(method, arguments); + + methods.add(method); + if (arguments is Map) { + argumentsLists.add(arguments.cast()); + if (arguments[paramOperations] != null) { + final operations = + arguments[paramOperations] as List>; + for (var operation in operations) { + final sql = operation[paramSql] as String?; + sqls.add(sql); + } + } else { + final sql = arguments[paramSql] as String?; + sqls.add(sql); + + // Basic version handling + if (sql?.startsWith('PRAGMA user_version = ') == true) { + version = int.tryParse(sql!.split(' ').last); + } else if (sql == 'PRAGMA user_version') { + return >[ + {'user_version': version} + ] as T; + } + } + } else { + argumentsLists.add(null); + sqls.add(null); + } + return mockResult(method, arguments) as T; + } +} + +class MockDatabaseFactory extends SqfliteDatabaseFactoryBase { + final List methods = []; + final List argumentsList = []; + final Map databases = {}; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + methods.add(method); + argumentsList.add(arguments); + return mockResult(method, arguments) as T; + } + + SqfliteDatabase newEmptyDatabase() { + final path = 'empty'; + final helper = SqfliteDatabaseOpenHelper(this, path, OpenDatabaseOptions()); + final db = helper.newDatabase(path)..id = 1; + return db; + } + + @override + SqfliteDatabaseMixin newDatabase( + SqfliteDatabaseOpenHelper openHelper, String path) { + final existing = databases[path]; + final db = MockDatabase(openHelper, path); + // Copy version + db.version = existing?.version; + // Last replaces + databases[path] = db; + + return db; + } + + @override + Future getDatabasesPath() async { + return join('.dart_tool', 'sqlite', 'test', 'mock'); + } +} + +class MockDatabaseFactoryEmpty extends SqfliteDatabaseFactoryBase { + final List methods = []; + + @override + Future invokeMethod(String method, [Object? arguments]) async { + methods.add(method); + return mockResult(method, arguments) as T; + } +} + +final MockDatabaseFactory mockDatabaseFactory = MockDatabaseFactory(); + +class SrcMixinTestPage extends TestPage { + SrcMixinTestPage(String title, {Key? key}) : super(title: title, key: key) { + group('database_factory', () { + test('SqfliteDatabaseFactoryBase.getDatabasesPath', () async { + final factory = MockDatabaseFactoryEmpty(); + await factory.getDatabasesPath(); + expect(factory.methods, ['getDatabasesPath']); + }); + test('SqfliteDatabaseFactoryBase.setDatabasesPath', () async { + final factory = MockDatabaseFactoryEmpty(); + + factory.setDatabasesPathOrNull('.'); + expect(await factory.getDatabasesPath(), '.'); + + // reset + factory.setDatabasesPathOrNull(null); + expect(factory.methods, []); + + await factory.getDatabasesPath(); + expect(factory.methods, ['getDatabasesPath']); + //expect(directory, ) + }); + }); + group('database', () { + test('Database.transaction', () async { + final Database db = mockDatabaseFactory.newEmptyDatabase(); + await db.execute('test'); + await db.insert('test', {'test': 1}); + await db.update('test', {'test': 1}); + await db.delete('test'); + await db.query('test'); + + await db.transaction((Transaction txn) async { + await txn.execute('test'); + await txn.insert('test', {'test': 1}); + await txn.update('test', {'test': 1}); + await txn.delete('test'); + await txn.query('test'); + }); + + final batch = db.batch(); + batch.execute('test'); + batch.insert('test', {'test': 1}); + batch.update('test', {'test': 1}); + batch.delete('test'); + batch.query('test'); + await batch.commit(); + }); + + group('open', () { + test('openDatabase() 指明只读模式', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase('test', + options: SqfliteOpenDatabaseOptions(readOnly: true)) + as MockDatabase; + await db.close(); + expect(db.methods, ['openDatabase', 'closeDatabase']); + expect(db.argumentsLists.first, { + 'path': absolute( + join(await mockDatabaseFactory.getDatabasesPath(), 'test')), + 'readOnly': true, + 'singleInstance': true + }); + }); + test('openDatabase() 指明不是单例', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase( + 'single_instance.db', + options: SqfliteOpenDatabaseOptions(singleInstance: false)) + as MockDatabase; + await db.close(); + expect(db.methods, ['openDatabase', 'closeDatabase']); + expect(db.argumentsLists.first, { + 'path': absolute(join(await mockDatabaseFactory.getDatabasesPath(), + 'single_instance.db')), + 'singleInstance': false + }); + }); + + test('Database.isOpen', () async { + // var db = mockDatabaseFactory.newEmptyDatabase(); + final db = await mockDatabaseFactory.openDatabase('is_open.db', + options: SqfliteOpenDatabaseOptions(readOnly: true)) + as MockDatabase; + expect(db.isOpen, true); + final closeFuture = db.close(); + // it is not closed right away + expect(db.isOpen, true); + await closeFuture; + expect(db.isOpen, false); + }); + + test('openDatabase() 指定version', () async { + var db = await mockDatabaseFactory.openDatabase('on_reopen.db', + options: OpenDatabaseOptions( + version: 1, + )) as MockDatabase; + await db.close(); + + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + + db = await mockDatabaseFactory.openDatabase('on_reopen.db', + options: OpenDatabaseOptions( + version: 1, + )) as MockDatabase; + await db.close(); + + // Re-opening, no transaction is created + expect(db.sqls, [null, 'PRAGMA user_version', null]); + }); + }); + group('openTransaction', () { + test('openDatabase() 在创建数据库时执行onCreate', () async { + final db = await mockDatabaseFactory.openDatabase('on_create.db', + options: SqfliteOpenDatabaseOptions( + version: 1, + onCreate: (Database db, int version) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'query', + 'execute', + 'query', + 'execute', + 'execute', + 'execute', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'test1', + 'test2', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + }); + + test('openDatabase() 打开数据库时优先执行onConfigure', () async { + final db = await mockDatabaseFactory.openDatabase('on_configure.db', + options: OpenDatabaseOptions( + version: 1, + onConfigure: (Database db) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'test1', + 'BEGIN IMMEDIATE', + 'test2', + 'COMMIT', + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + null + ]); + }); + + test('openDatabase() 设置数据库版本后执行onOpen', () async { + final db = await mockDatabaseFactory.openDatabase('on_open', + options: OpenDatabaseOptions( + version: 1, + onOpen: (Database db) async { + await db.execute('test1'); + await db.transaction((Transaction txn) async { + await txn.execute('test2'); + }); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'PRAGMA user_version = 1', + 'COMMIT', + 'test1', + 'BEGIN IMMEDIATE', + 'test2', + 'COMMIT', + null + ]); + }); + + test('Database.batch', () async { + final db = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions( + version: 1, + onConfigure: (Database db) async { + final batch = db.batch(); + batch.execute('test1'); + await batch.commit(); + }, + onCreate: (db, _) async { + final batch = db.batch(); + batch.execute('test2'); + await batch.commit(noResult: true); + }, + onOpen: (Database db) async { + final batch = db.batch(); + batch.execute('test3'); + await batch.commit(continueOnError: true); + })) as MockDatabase; + + await db.close(); + expect(db.sqls, [ + null, + 'BEGIN IMMEDIATE', + 'test1', + 'COMMIT', + 'PRAGMA user_version', + 'BEGIN EXCLUSIVE', + 'PRAGMA user_version', + 'test2', + 'PRAGMA user_version = 1', + 'COMMIT', + 'BEGIN IMMEDIATE', + 'test3', + 'COMMIT', + null + ]); + expect(db.argumentsLists, [ + { + 'path': absolute( + join(await mockDatabaseFactory.getDatabasesPath(), 'test')), + 'singleInstance': true + }, + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null + }, + { + 'operations': [ + { + 'method': 'execute', + 'sql': 'test1', + } + ], + 'id': 1 + }, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + {'sql': 'PRAGMA user_version', 'id': 1}, + { + 'sql': 'BEGIN EXCLUSIVE', + 'inTransaction': true, + 'id': 1, + 'transactionId': null + }, + {'sql': 'PRAGMA user_version', 'id': 1}, + { + 'operations': >[ + { + 'method': 'execute', + 'sql': 'test2', + } + ], + 'id': 1, + 'noResult': true + }, + {'sql': 'PRAGMA user_version = 1', 'id': 1}, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + { + 'sql': 'BEGIN IMMEDIATE', + 'id': 1, + 'inTransaction': true, + 'transactionId': null, + }, + { + 'operations': >[ + { + 'method': 'execute', + 'sql': 'test3', + } + ], + 'id': 1, + 'continueOnError': true + }, + {'sql': 'COMMIT', 'id': 1, 'inTransaction': false}, + {'id': 1} + ]); + }); + }); + + group('并发测试', () { + test('concurrent 1', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db + .execute('test') + .timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + // This is the change with concurrency 2 + await step1.future; + await db.transaction((Transaction txn) async { + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction(((_) async {})); + }); + + test('concurrent 2', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db + .execute('test') + .timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + await db.transaction((Transaction txn) async { + await step1.future; + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + }); + }); + + group('compatibility 1', () { + test('concurrent 1', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await db.execute('test'); + step1.complete(); + + await step2.future; + try { + await db + .execute('test') + .timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + // This is the change with concurrency 2 + await step1.future; + await db.transaction((Transaction txn) async { + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future1 = action1(); + final Future future2 = action2(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction(((_) async {})); + }); + + test('concurrent 2', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + final step1 = Completer(); + final step2 = Completer(); + final step3 = Completer(); + + Future action1() async { + await step1.future; + try { + await db + .execute('test') + .timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + await step2.future; + try { + await db + .execute('test') + .timeout(const Duration(milliseconds: 100)); + throw 'should fail'; + } catch (e) { + expect(e is TimeoutException, true); + } + + step3.complete(); + } + + Future action2() async { + await db.transaction((Transaction txn) async { + step1.complete(); + + // Wait for table being created; + await txn.execute('test'); + step2.complete(); + + await step3.future; + + await txn.execute('test'); + }); + } + + final Future future2 = action2(); + final Future future1 = action1(); + + await Future.wait(>[future1, future2]); + // check ready + await db.transaction(((_) async {})); + }); + }); + + group('batch', () { + test('simple', () async { + final db = await mockDatabaseFactory.openDatabase('batch_simple.db') + as MockDatabase; + + final batch = db.batch(); + batch.execute('test'); + await batch.commit(); + await batch.commit(); + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'execute', + 'batch', + 'execute', + 'execute', + 'batch', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, [ + null, + 'BEGIN IMMEDIATE', + 'test', + 'COMMIT', + 'BEGIN IMMEDIATE', + 'test', + 'COMMIT', + null + ]); + }); + + test('Database.transaction', () async { + final db = await mockDatabaseFactory + .openDatabase('batch_in_transaction.db') as MockDatabase; + + await db.transaction((Transaction txn) async { + final batch = txn.batch(); + batch.execute('test'); + + await batch.commit(); + await batch.commit(); + }); + await db.close(); + expect(db.methods, [ + 'openDatabase', + 'execute', + 'batch', + 'batch', + 'execute', + 'closeDatabase' + ]); + expect(db.sqls, [ + null, + 'BEGIN IMMEDIATE', + 'test', + 'test', + 'COMMIT', + null + ]); + }); + }); + + group('单例数据库测试', () { + test('singleInstance==true', () async { + final futureDb1 = mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)); + final db2 = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)) + as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + expect(db1, db2); + }); + test('singleInstance', () async { + final futureDb1 = mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)); + final db2 = await mockDatabaseFactory.openDatabase('test', + options: OpenDatabaseOptions(singleInstance: true)) + as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + final db3 = await mockDatabaseFactory.openDatabase('other', + options: OpenDatabaseOptions(singleInstance: true)) + as MockDatabase; + final db4 = await mockDatabaseFactory.openDatabase(join('.', 'other'), + options: OpenDatabaseOptions(singleInstance: true)) + as MockDatabase; + //expect(db1, db2); + expect(db1, db3); + expect(db3, db4); + await db1.close(); + await db2.close(); + await db3.close(); + }); + + test('multiInstances', () async { + final futureDb1 = mockDatabaseFactory.openDatabase( + 'multi_instances.db', + options: OpenDatabaseOptions(singleInstance: false)); + final db2 = await mockDatabaseFactory.openDatabase( + 'multi_instances.db', + options: OpenDatabaseOptions(singleInstance: false)) + as MockDatabase; + final db1 = await futureDb1 as MockDatabase; + expect(db1, db2); + await db1.close(); + await db2.close(); + }); + }); + + test('setLockWarningInfo', () async { + final db = mockDatabaseFactory.newEmptyDatabase() as MockDatabase; + var hasTimedOut = false; + var callbackCount = 0; + setLockWarningInfo( + duration: const Duration(milliseconds: 200), + callback: () { + callbackCount++; + }); + try { + await db.transaction((Transaction txn) async { + await db.execute('test'); + fail('should fail'); + }).timeout(const Duration(milliseconds: 500)); + } on TimeoutException catch (_) { + hasTimedOut = true; + } + expect(hasTimedOut, true); + expect(callbackCount, 1); + await db.close(); + }); + + test('deleteDatabase databaseExists', () async { + const path = 'test_exists.db'; + await mockDatabaseFactory.deleteDatabase(path); + final exists = await mockDatabaseFactory.databaseExists(path); + expect(exists, true); + final expectedPath = + absolute(join(await mockDatabaseFactory.getDatabasesPath(), path)); + expect(mockDatabaseFactory.methods, + ['deleteDatabase', 'databaseExists']); + expect(mockDatabaseFactory.argumentsList, >[ + {'path': expectedPath}, + {'path': expectedPath} + ]); + }); + }); + } +} diff --git a/ohos/test_sqflite_common/lib/src/test_scenario.dart b/ohos/test_sqflite_common/lib/src/test_scenario.dart new file mode 100644 index 0000000000000000000000000000000000000000..e653045a0e697fa12b0c1b9e306db3efc10c3968 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/test_scenario.dart @@ -0,0 +1,89 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/sqlite_api.dart'; +import 'package:sqflite_common/src/mixin/import_mixin.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +/// Common open step +var protocolOpenStep = [ + 'openDatabase', + {'path': ':memory:', 'singleInstance': false}, + {'id': 1} +]; + +/// Common close step +var protocolCloseStep = [ + 'closeDatabase', + {'id': 1}, + null +]; + +class MockMethodCall { + String? expectedMethod; + dynamic expectedArguments; + + /// Response can be an exception + dynamic response; + + @override + String toString() => '$expectedMethod $expectedArguments $response'; +} + +class MockScenario { + MockScenario(this.factory, List data) { + methodsCalls = data + .map((list) => MockMethodCall() + ..expectedMethod = list[0]?.toString() + ..expectedArguments = list[1] + ..response = list[2]) + .toList(growable: false); + } + + final DatabaseFactory factory; + late List methodsCalls; + var index = 0; + dynamic exception; + + void end() { + expect(exception, null); + expect(index, methodsCalls.length); + } +} + +MockScenario startScenario(List data) { + late MockScenario scenario; + final databaseFactoryMock = buildDatabaseFactory( + tag: 'mock', + invokeMethod: (String method, [Object? arguments]) async { + final index = scenario.index++; + // devPrint('$index ${scenario.methodsCalls[index]}'); + final item = scenario.methodsCalls[index]; + try { + expect(method, item.expectedMethod); + expect(arguments, item.expectedArguments); + } catch (e) { + // devPrint(e); + scenario.exception ??= '$e $index'; + } + if (item.response is DatabaseException) { + throw item.response as DatabaseException; + } + return item.response; + }); + scenario = MockScenario(databaseFactoryMock, data); + return scenario; +} diff --git a/ohos/test_sqflite_common/lib/src/utils_test.dart b/ohos/test_sqflite_common/lib/src/utils_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..80bcc52652ff5dd2b6e5e056c698b5212de08b45 --- /dev/null +++ b/ohos/test_sqflite_common/lib/src/utils_test.dart @@ -0,0 +1,91 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:sqflite_common/src/utils.dart'; +import 'package:sqflite_common/utils/utils.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; +import '../common/test_page.dart'; + +class UtilsTestPage extends TestPage { + UtilsTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('sqflite', () { + test('firstIntValue', () { + expect( + firstIntValue(>[ + {'test': 1} + ]), + 1); + expect( + firstIntValue(>[ + {'test': 1}, + {'test': 1} + ]), + 1); + expect( + firstIntValue(>[ + {'test': null} + ]), + null); + expect(firstIntValue(>[{}]), null); + expect(firstIntValue(>[]), null); + expect(firstIntValue(>[{}]), null); + }); + + test('hex', () { + expect(hex([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 255]), '000102030405060708090A0B0C0D0E0F1011FF'); + expect(hex([]), ''); + expect(hex([32]), '20'); + + try { + hex([-1]); + fail('should fail'); + } on FormatException catch (_) {} + + try { + hex([256]); + fail('should fail'); + } on FormatException catch (_) {} + }); + + test('listChunk', () { + expect(listChunk([], null), null); + expect(listChunk([1], null), [ + [1] + ]); + expect(listChunk([1], 0), [ + [1] + ]); + expect(listChunk([1, 2], 0), [ + [1, 2] + ]); + expect(listChunk([1, 2], 2), [ + [1, 2] + ]); + expect(listChunk([1, 2], 3), [ + [1, 2] + ]); + expect(listChunk([1, 2], 1), [ + [1], + [2] + ]); + expect(listChunk([1, 2, 3], 2), [ + [1, 2], + [3] + ]); + }); + }); + } +} diff --git a/ohos/test_sqflite_common/ohos/.gitignore b/ohos/test_sqflite_common/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/AppScope/app.json5 b/ohos/test_sqflite_common/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..eb963ef2983ae14605ca911ff046d0e96f501211 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_sqflite_common", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_sqflite_common/ohos/AppScope/resources/base/element/string.json b/ohos/test_sqflite_common/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..149c0f26e0cfce5e7efe2d381a5717bcc8276234 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_sqflite_common" + } + ] +} diff --git a/ohos/test_sqflite_common/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_sqflite_common/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_sqflite_common/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_sqflite_common/ohos/build-profile.json5 b/ohos/test_sqflite_common/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..ee2d6534772532ce7f9517d131da3f198696bed6 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite_common.cer", + "storePassword": "0000001B0FC1456CD6FF54E0C366F8D24DC85675010A0579CA6B2A436DD8E63EB4516665DE83FCE2971EEA", + "keyAlias": "debugKey", + "keyPassword": "0000001BBD640109678B3F64F3425EEFCB07F14E9FAEBB6AE37B2B573D9C797421CFAF2236ACEA538FF630", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite_common.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_sqflite_common.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_sqflite_common/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_sqflite_common/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_sqflite_common/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_sqflite_common/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_sqflite_common/ohos/dependencies/rollup.tgz b/ohos/test_sqflite_common/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_sqflite_common/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_sqflite_common/ohos/dta/icudtl.dat b/ohos/test_sqflite_common/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/dta/icudtl.dat differ diff --git a/ohos/test_sqflite_common/ohos/entry/.gitignore b/ohos/test_sqflite_common/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/build-profile.json5 b/ohos/test_sqflite_common/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/hvigorfile.ts b/ohos/test_sqflite_common/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_sqflite_common/ohos/entry/oh-package.json5 b/ohos/test_sqflite_common/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_sqflite_common/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_sqflite_common/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/module.json5 b/ohos/test_sqflite_common/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3abf18c41c58c933308c244a875bf383856e103e --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]}] \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..e1f7aab5994d304cf0ad3130000f4810cd11f83d Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..52c0f850ecc0f518ba7c4440f657a7f3243276e9 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_sqflite_common/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/module.json5 b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_sqflite_common/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_sqflite_common/ohos/har/flutter_embedding.har b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.10 b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.9 b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_sqflite_common/ohos/har/libflutter.so.debug.10 b/ohos/test_sqflite_common/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_sqflite_common/ohos/har/libflutter.so.release.10 b/ohos/test_sqflite_common/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_sqflite_common/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_sqflite_common/ohos/hvigor/hvigor-config.json5 b/ohos/test_sqflite_common/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_sqflite_common/ohos/hvigor/hvigor-wrapper.js b/ohos/test_sqflite_common/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/hvigorfile.ts b/ohos/test_sqflite_common/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_sqflite_common/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/hvigorw b/ohos/test_sqflite_common/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_sqflite_common/ohos/hvigorw.bat b/ohos/test_sqflite_common/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_sqflite_common/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_sqflite_common/ohos/oh-package-lock.json5 b/ohos/test_sqflite_common/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_sqflite_common/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_sqflite_common/ohos/oh-package.json5 b/ohos/test_sqflite_common/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_sqflite_common/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_sqflite_common/pubspec.yaml b/ohos/test_sqflite_common/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..534a91976dc556900ff86f1c157df1fb6b315eb4 --- /dev/null +++ b/ohos/test_sqflite_common/pubspec.yaml @@ -0,0 +1,32 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_sqflite_common +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 +environment: + sdk: '>=2.19.6 <3.0.0' + +dependencies: + flutter: + sdk: flutter + sqflite_common: 2.4.5+1 +dev_dependencies: + lints: ^1.0.0 + test: ^1.16.0 +flutter: + uses-material-design: true + \ No newline at end of file diff --git a/ohos/test_synchronized/.gitignore b/ohos/test_synchronized/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_synchronized/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_synchronized/.metadata b/ohos/test_synchronized/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_synchronized/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_synchronized/README.md b/ohos/test_synchronized/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_synchronized/analysis_options.yaml b/ohos/test_synchronized/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_synchronized/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_synchronized/lib/common/base_page.dart b/ohos/test_synchronized/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_synchronized/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_synchronized/lib/common/item_widget.dart b/ohos/test_synchronized/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_synchronized/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_synchronized/lib/common/main_item_widget.dart b/ohos/test_synchronized/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_synchronized/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_synchronized/lib/common/test_model_app.dart b/ohos/test_synchronized/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_synchronized/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_synchronized/lib/common/test_page.dart b/ohos/test_synchronized/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_synchronized/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_synchronized/lib/common/test_route.dart b/ohos/test_synchronized/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_synchronized/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_synchronized/lib/main.dart b/ohos/test_synchronized/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..4cf6d30d84846fc61fc512a1f4063a40e29a2ebd --- /dev/null +++ b/ohos/test_synchronized/lib/main.dart @@ -0,0 +1,43 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; +import 'package:test_synchronized/src/basic_lock_test.dart'; +import 'package:test_synchronized/src/common_lock_test.dart'; +import 'package:test_synchronized/src/extension_lock_impl_test.dart'; +import 'package:test_synchronized/src/extension_lock_test.dart'; +import 'package:test_synchronized/src/issues_test.dart'; +import 'package:test_synchronized/src/perf_test.dart'; +import 'package:test_synchronized/src/reentrant_lock_test.dart'; +import 'package:test_synchronized/src/synchronized_impl_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + final app = [ + MainItem('BasicLock', BasicLockTestPage('BasicLock')), + MainItem('CommonLock', CommonLockTestPage('CommonLock')), + MainItem('extension_lock_impl_test', ExtensionLockImplTestPage('extension_lock_impl_test')), + MainItem('extension_lock_test', ExtensionLockTestPage('extension_lock_test')), + MainItem('issues_test', IssuesTestPage('issues_test')), + MainItem('perf_test', PerfTestPage('perf_test')), + MainItem('reentrant_lock_test', ReentrantLockTestPage('reentrant_lock_test')), + MainItem('synchronized_impl_test', SynchronizedImplTestPage('synchronized_impl_test')), + ]; + + runApp(TestModelApp(appName: 'synchronized', data: app)); +} diff --git a/ohos/test_synchronized/lib/src/basic_lock_test.dart b/ohos/test_synchronized/lib/src/basic_lock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..94c4c2037935b57953bdc56ed672447565658f27 --- /dev/null +++ b/ohos/test_synchronized/lib/src/basic_lock_test.dart @@ -0,0 +1,455 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/synchronized.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; +import 'package:synchronized/src/basic_lock.dart'; +import 'lock_factory.dart'; + +class BasicLockTestPage extends TestPage { + BasicLockTestPage(String title, {Key? key}) : super(title: title, key: key) { + final lockFactory = BasicLockFactory(); + group('BasicLock', () { + // Common tests + lockMain(lockFactory); + + test('不能同时进行操作', () async { + final lock = Lock(); + Object? exception; + await lock.synchronized(() async { + try { + await lock.synchronized(() {}, timeout: const Duration(seconds: 1)); + } catch (e) { + exception = e; + } + }); + expect(exception, null); + }); + }); + } + + void lockMain(LockFactory lockFactory) { + Lock newLock() => lockFactory.newLock(); + + group('synchronized', () { + test('两个lock锁', () async { + var lock1 = newLock(); + var lock2 = newLock(); + + bool? ok; + await lock1.synchronized(() async { + await lock2.synchronized(() async { + expect(lock2.locked, true); + ok = true; + }); + }); + expect(ok, true); + }); + + test('按顺序加锁', () async { + final lock = newLock(); + final list = []; + final future1 = lock.synchronized(() async { + list.add(1); + }); + final future2 = lock.synchronized(() async { + await sleep(10); + list.add(2); + return 'text'; + }); + final future3 = lock.synchronized(() { + list.add(3); + return 1234; + }); + expect(list, [1]); + await Future.wait([future1, future2, future3]); + expect(await future1, null); + expect(await future2, 'text'); + expect(await future3, 1234); + expect(list, [1, 2, 3]); + }); + + test('排队等锁结束后取值', () async { + final lock = newLock(); + final value1 = lock.synchronized(() async { + await sleep(1); + return 'value1'; + }); + expect(await lock.synchronized(() => 'value2'), 'value2'); + expect(await value1, 'value1'); + }); + + group('perf', () { + final operationCount = 10000; + + test('$operationCount 次操作', () async { + var count = operationCount; + int j; + + final sw1 = Stopwatch(); + j = 0; + sw1.start(); + for (var i = 0; i < count; i++) { + j += i; + } + sw1.stop(); + expect(j, count * (count - 1) / 2); + + final sw2 = Stopwatch(); + j = 0; + sw2.start(); + for (var i = 0; i < count; i++) { + await () async { + j += i; + }(); + } + sw2.stop(); + expect(j, count * (count - 1) / 2); + + var lock = newLock(); + final sw3 = Stopwatch(); + j = 0; + sw3.start(); + for (var i = 0; i < count; i++) { + // ignore: unawaited_futures + lock.synchronized(() { + j += i; + }); + } + // final wait + await lock.synchronized(() => {}); + expect(lock.locked, false); + sw3.stop(); + expect(j, count * (count - 1) / 2); + + final sw4 = Stopwatch(); + j = 0; + sw4.start(); + for (var i = 0; i < count; i++) { + await lock.synchronized(() async { + await Future.value(); + j += i; + }); + } + // final wait + expect(lock.locked, false); + sw4.stop(); + expect(j, count * (count - 1) / 2); + + print(' none ${sw1.elapsed}'); + print(' await ${sw2.elapsed}'); + print(' syncd ${sw3.elapsed}'); + print('asyncd ${sw4.elapsed}'); + }); + }); + + group('timeout', () { + test('1_ms后再次获取', () async { + final lock = newLock(); + final completer = Completer(); + final future = lock.synchronized(() async { + await completer.future; + }); + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.complete(); + await future; + }); + + test('100_ms后再次获取', () async { + // var isNewTiming = await isDart2AsyncTiming(); + // hoping timint is ok... + final lock = newLock(); + + var ran1 = false; + var ran2 = false; + var ran3 = false; + var ran4 = false; + // hold for 5ms + // ignore: unawaited_futures + lock.synchronized(() async { + await sleep(1000); + }); + + try { + await lock.synchronized(() { + ran1 = true; + }, timeout: const Duration(milliseconds: 1)); + } on TimeoutException catch (_) {} + + try { + await lock.synchronized(() async { + await sleep(5000); + ran2 = true; + }, timeout: const Duration(milliseconds: 1)); + // fail('should fail'); + } on TimeoutException catch (_) {} + + try { + // ignore: unawaited_futures + lock.synchronized(() { + ran4 = true; + }, timeout: const Duration(milliseconds: 2000)); + } on TimeoutException catch (_) {} + + // waiting long enough + await lock.synchronized(() { + ran3 = true; + }, timeout: const Duration(milliseconds: 2000)); + + expect(ran1, false); + expect(ran2, false); + expect(ran3, true); + expect(ran4, true); + }); + + test('1_ms_with_error,1ms后再次获取并报错, 此处已处理', () async { + var ok = false; + var okTimeout = false; + try { + final lock = newLock(); + final completer = Completer(); + unawaited(lock.synchronized(() async { + await completer.future; + }).catchError((e) {})); + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.completeError('error'); + + // Make sure these block ran + await lock.synchronized(() { + ok = true; + }); + await lock.synchronized(() { + okTimeout = true; + }, timeout: const Duration(milliseconds: 1000)); + } catch (_) {} + expect(ok, true); + expect(okTimeout, true); + }); + }); + + group('error', () { + test('throw', () async { + final lock = newLock(); + try { + await lock.synchronized(() { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('queued_throw', () async { + final lock = newLock(); + + // delay so that it is queued + // ignore: unawaited_futures + lock.synchronized(() { + return sleep(1); + }); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('throw_async', () async { + final lock = newLock(); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + }); + }); + + group('immediacity', () { + test('sync', () async { + var lock = newLock(); + int? value; + final future = lock.synchronized(() { + value = 1; + return Future.value().then((_) { + value = 2; + }); + }); + // A sync method is executed right away! + expect(value, 1); + await future; + expect(value, 2); + }); + + test('async', () async { + var lock = newLock(); + int? value; + final future = lock.synchronized(() async { + value = 1; + return Future.value().then((_) { + value = 2; + }); + }); + // A sync method is executed right away! + expect(value, 1); + + await future; + expect(value, 2); + }); + }); + + group('locked', () { + test('简单开所关锁', () async { + // Make sure the lock state is made immediately + // when the function is not async + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() => {}); + expect(lock.locked, false); + await future; + expect(lock.locked, false); + }); + + test('异步查看锁定状态', () async { + // Make sure the lock state is lazy for async method + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() async => {}); + expect(lock.locked, true); + await future; + expect(lock.locked, false); + }); + }); + group('在锁定时判断锁定状态', () { + test('two', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + + unawaited(lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + })); + + await lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('判断是否锁是否开启', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('锁定', () async { + final lock = newLock(); + final completer = Completer(); + expect(lock.locked, false); + expect(lock.inLock, false); + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + if (lock is BasicLock) { + expect(lock.inLock, true); + } + completer.complete(); + await future; + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('超时锁定', () async { + final lock = newLock(); + final completer = Completer(); + + // Lock it forever + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + + // Expect a time out exception + var hasTimeoutException = false; + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) { + // Timeout exception expected + hasTimeoutException = true; + } + expect(hasTimeoutException, true); + expect(lock.locked, true); + // Release the forever waiting lock + completer.complete(); + await future; + expect(lock.locked, false); + + // Should succeed right away + await lock.synchronized(() {}, timeout: const Duration(seconds: 10)); + }); + }); + }); + } +} diff --git a/ohos/test_synchronized/lib/src/common_lock_test.dart b/ohos/test_synchronized/lib/src/common_lock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..bf879fc96c284f2cb043f8c2c738cbe320f1f105 --- /dev/null +++ b/ohos/test_synchronized/lib/src/common_lock_test.dart @@ -0,0 +1,426 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/src/basic_lock.dart'; +import 'package:synchronized/synchronized.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +import 'lock_factory.dart'; + +class CommonLockTestPage extends TestPage { + CommonLockTestPage(String title,{ Key? key}) : super(title: title, key: key) { + + group('synchronized', () { + test('两个锁', () async { + var lock1 = newLock(); + var lock2 = newLock(); + + bool? ok; + await lock1.synchronized(() async { + await lock2.synchronized(() async { + expect(lock2.locked, true); + ok = true; + }); + }); + expect(ok, true); + }); + + test('order', () async { + final lock = newLock(); + final list = []; + final future1 = lock.synchronized(() async { + list.add(1); + }); + final future2 = lock.synchronized(() async { + await sleep(10); + list.add(2); + return 'text'; + }); + final future3 = lock.synchronized(() { + list.add(3); + return 1234; + }); + expect(list, [1]); + await Future.wait([future1, future2, future3]); + expect(await future1, null); + expect(await future2, 'text'); + expect(await future3, 1234); + expect(list, [1, 2, 3]); + }); + + test('queued_value', () async { + final lock = newLock(); + final value1 = lock.synchronized(() async { + await sleep(1); + return 'value1'; + }); + expect(await lock.synchronized(() => 'value2'), 'value2'); + expect(await value1, 'value1'); + }); + + group('perf', () { + final operationCount = 10000; + + test('$operationCount operations', () async { + var count = operationCount; + int j; + + final sw1 = Stopwatch(); + j = 0; + sw1.start(); + for (var i = 0; i < count; i++) { + j += i; + } + sw1.stop(); + expect(j, count * (count - 1) / 2); + + final sw2 = Stopwatch(); + j = 0; + sw2.start(); + for (var i = 0; i < count; i++) { + await () async { + j += i; + }(); + } + sw2.stop(); + expect(j, count * (count - 1) / 2); + + var lock = newLock(); + final sw3 = Stopwatch(); + j = 0; + sw3.start(); + for (var i = 0; i < count; i++) { + // ignore: unawaited_futures + lock.synchronized(() { + j += i; + }); + } + // final wait + await lock.synchronized(() => {}); + expect(lock.locked, false); + sw3.stop(); + expect(j, count * (count - 1) / 2); + + final sw4 = Stopwatch(); + j = 0; + sw4.start(); + for (var i = 0; i < count; i++) { + await lock.synchronized(() async { + await Future.value(); + j += i; + }); + } + // final wait + expect(lock.locked, false); + sw4.stop(); + expect(j, count * (count - 1) / 2); + + print(' none ${sw1.elapsed}'); + print(' await ${sw2.elapsed}'); + print(' syncd ${sw3.elapsed}'); + print('asyncd ${sw4.elapsed}'); + }); + }); + + group('timeout', () { + test('1_ms', () async { + final lock = newLock(); + final completer = Completer(); + final future = lock.synchronized(() async { + await completer.future; + }); + try { + await lock.synchronized(() {}, + timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.complete(); + await future; + }); + + test('100_ms', () async { + // var isNewTiming = await isDart2AsyncTiming(); + // hoping timint is ok... + final lock = newLock(); + + var ran1 = false; + var ran2 = false; + var ran3 = false; + var ran4 = false; + // hold for 5ms + // ignore: unawaited_futures + lock.synchronized(() async { + await sleep(1000); + }); + + try { + await lock.synchronized(() { + ran1 = true; + }, timeout: const Duration(milliseconds: 1)); + } on TimeoutException catch (_) {} + + try { + await lock.synchronized(() async { + await sleep(5000); + ran2 = true; + }, timeout: const Duration(milliseconds: 1)); + // fail('should fail'); + } on TimeoutException catch (_) {} + + try { + // ignore: unawaited_futures + lock.synchronized(() { + ran4 = true; + }, timeout: const Duration(milliseconds: 2000)); + } on TimeoutException catch (_) {} + + // waiting long enough + await lock.synchronized(() { + ran3 = true; + }, timeout: const Duration(milliseconds: 2000)); + + expect(ran1, false); + expect(ran2, false); + expect(ran3, true); + expect(ran4, true); + }); + + test('1_ms_with_error', () async { + var ok = false; + var okTimeout = false; + try { + final lock = newLock(); + final completer = Completer(); + unawaited(lock.synchronized(() async { + await completer.future; + }).catchError((e) {})); + try { + await lock.synchronized(() {}, + timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.completeError('error'); + // await future; + // await lock.synchronized(null, timeout: Duration(milliseconds: 1000)); + + // Make sure these block ran + await lock.synchronized(() { + ok = true; + }); + await lock.synchronized(() { + okTimeout = true; + }, timeout: const Duration(milliseconds: 1000)); + } catch (_) {} + expect(ok, true); + expect(okTimeout, true); + }); + }); + + group('error', () { + test('抛出一个异常', () async { + final lock = newLock(); + try { + await lock.synchronized(() { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('排队抛出异常', () async { + final lock = newLock(); + + // delay so that it is queued + // ignore: unawaited_futures + lock.synchronized(() { + return sleep(1); + }); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('异步抛出异常', () async { + final lock = newLock(); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + }); + }); + + group('immediacity', () { + test('异步修改值', () async { + var lock = newLock(); + int? value; + final future = lock.synchronized(() async { + value = 1; + return Future.value().then((_) { + value = 2; + }); + }); + // A sync method is executed right away! + expect(value, 1); + + await future; + expect(value, 2); + }); + }); + + group('locked', () { + test('简单开锁关锁', () async { + // Make sure the lock state is made immediately + // when the function is not async + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() => {}); + expect(lock.locked, false); + await future; + expect(lock.locked, false); + }); + + test('异步查看锁定状态', () async { + // Make sure the lock state is lazy for async method + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() async => {}); + expect(lock.locked, true); + await future; + expect(lock.locked, false); + }); + }); + group('在锁定时检查锁定状态', () { + test('two', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + + unawaited(lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + })); + + await lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('测试简单开锁关锁', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('测试锁定', () async { + final lock = newLock(); + final completer = Completer(); + expect(lock.locked, false); + expect(lock.inLock, false); + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + if (lock is BasicLock) { + expect(lock.inLock, true); + } + completer.complete(); + await future; + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('超时锁定', () async { + final lock = newLock(); + final completer = Completer(); + + // Lock it forever + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + + // Expect a time out exception + var hasTimeoutException = false; + try { + await lock.synchronized(() {}, + timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) { + // Timeout exception expected + hasTimeoutException = true; + } + expect(hasTimeoutException, true); + expect(lock.locked, true); + // Release the forever waiting lock + completer.complete(); + await future; + expect(lock.locked, false); + + // Should succeed right away + await lock.synchronized(() {}, timeout: const Duration(seconds: 10)); + }); + }); + }); + } + + Lock newLock() => BasicLockFactory().newLock(); +} diff --git a/ohos/test_synchronized/lib/src/extension_lock_impl_test.dart b/ohos/test_synchronized/lib/src/extension_lock_impl_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..1a775a616fb74c5aeae0d65119010c04a0119f4a --- /dev/null +++ b/ohos/test_synchronized/lib/src/extension_lock_impl_test.dart @@ -0,0 +1,38 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/extension.dart'; +import 'package:synchronized/src/basic_lock.dart'; +import 'package:synchronized/src/extension_impl.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class ExtensionLockImplTestPage extends TestPage { + ExtensionLockImplTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('extension_impl', () { + test('静态锁', () async { + expect(cacheLocks, {}); + await 'test'.synchronized(() { + expect(cacheLocks['test'], null); + }); + expect(cacheLocks, {}); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/lib/src/extension_lock_test.dart b/ohos/test_synchronized/lib/src/extension_lock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..c4bd3bc5eb2021bed30bb4493c01e318ea734979 --- /dev/null +++ b/ohos/test_synchronized/lib/src/extension_lock_test.dart @@ -0,0 +1,115 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/extension.dart'; +import 'package:synchronized/src/utils.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class MyClass { + MyClass(this.text); + + final String text; + + /// Perform a long action that won't be called more than once at a time. + Future performClassAction() { + // Lock at the class level + return runtimeType.synchronized(() async { + // ...uninterrupted action + }); + } + + /// Perform a long action that won't be called more than once at a time. + Future performAction() { + // Lock at the class level + return synchronized(() async { + // ...uninterrupted action + }); + } + + @override + int get hashCode => text.hashCode; + + @override + bool operator ==(other) { + if (other is MyClass) { + return (other.text == text); + } + return false; + } +} + +class ExtensionLockTestPage extends TestPage { + ExtensionLockTestPage(String title, {Key? key}) + : super(title: title, key: key) { + group('extension', () { + test('锁定时等待一段时间后操作list', () async { + final lock = 'test'; + final list = []; + final future1 = lock.synchronized(() async { + list.add(1); + }); + final future2 = ('${'te'}${'st'}').synchronized(() async { + await sleep(10); + list.add(2); + return 'text'; + }); + final future3 = lock.synchronized(() { + list.add(3); + return 1234; + }); + expect(list, [1]); + await Future.wait([future1, future2, future3]); + expect(await future1, null); + expect(await future2, 'text'); + expect(await future3, 1234); + expect(list, [1, 2, 3]); + }); + + test('不能重新锁定', () async { + Object? exception; + await 'non-reentrant'.synchronized(() async { + try { + await 'non-reentrant' + .synchronized(() {}, timeout: const Duration(seconds: 1)); + } catch (e) { + exception = e; + } + }); + expect(exception, null); + }); + + test('重新锁定一个类', () async { + await MyClass('non-reentrant').synchronized(() async { + await MyClass('non-reentrant-distinct') + .synchronized(() {}, timeout: const Duration(seconds: 1)); + }); + }); + + test('锁定一个类', () async { + var myObject = MyClass('doc'); + + // ignore: unawaited_futures + myObject.synchronized(() async { + // ...uninterrupted action + }); + }); + }); + } +} diff --git a/ohos/test_synchronized/lib/src/issues_test.dart b/ohos/test_synchronized/lib/src/issues_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..b53fe17011818e7538473777eba4d46493f03e61 --- /dev/null +++ b/ohos/test_synchronized/lib/src/issues_test.dart @@ -0,0 +1,99 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/src/utils.dart'; +import 'package:synchronized/synchronized.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class IssuesTestPage extends TestPage { + IssuesTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('issues', () { + // https://github.com/tekartik/synchronized.dart/issues/22 + test('尝试获取锁,这将失败,并出现超时异常', () async { + var lock = Lock(); + + // Create a long synchronized function but don't wait for it + unawaited(lock.synchronized(() async { + await Future.delayed(const Duration(hours: 1)); + })); + + // Try to grab the lock, this should fail with a time out exception + try { + await lock.synchronized(() async { + // We should never get there + fail('should timeout'); + }, timeout: const Duration(milliseconds: 100)); + } on TimeoutException catch (_) {} + }); + + test('结束前松开锁', () async { + var lock = Lock(); + + try { + // Create a long synchronized function that times out + await lock.synchronized(() async { + Future longAction() async { + // Do you action here... + await Future.delayed(const Duration(hours: 1)); + } + + // Release the lock before the end + await longAction().timeout(const Duration(milliseconds: 100)); + }); + } on TimeoutException catch (_) {} + }); + // https://github.com/tekartik/synchronized.dart/issues/1 + test('结束后松开锁', () async { + var value = ''; + var lock = Lock(reentrant: true); + + final outer1 = lock.synchronized(() async { + expect(value,('')); + value = 'outer1'; + + await sleep(20); + + await lock.synchronized(() async { + await sleep(30); + expect(value, ('outer1')); + value = 'inner1'; + }); + }); + + final outer2 = lock.synchronized(() async { + await sleep(30); + expect(value, ('inner1')); + value = 'outer2'; + }); + + final outer3 = sleep(30).whenComplete(() { + return lock.synchronized(() async { + expect(value, ('outer2')); + value = 'outer3'; + }); + }); + + await Future.wait([outer1, outer2, outer3]); + + expect(value, ('outer3')); + }); + }); + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/lib/src/lock_factory.dart b/ohos/test_synchronized/lib/src/lock_factory.dart new file mode 100644 index 0000000000000000000000000000000000000000..628abc89201589f42fecb42658dbab36032d8268 --- /dev/null +++ b/ohos/test_synchronized/lib/src/lock_factory.dart @@ -0,0 +1,34 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:synchronized/src/basic_lock.dart'; +import 'package:synchronized/src/reentrant_lock.dart'; +import 'package:synchronized/synchronized.dart'; + +export 'package:synchronized/src/utils.dart'; + +abstract class LockFactory { + Lock newLock(); +} + +class BasicLockFactory implements LockFactory { + @override + Lock newLock() => BasicLock(); +} + +class ReentrantLockFactory implements LockFactory { + @override + Lock newLock() => ReentrantLock(); +} diff --git a/ohos/test_synchronized/lib/src/perf_test.dart b/ohos/test_synchronized/lib/src/perf_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..e53d98399f89202c872c8337fe0863ef10c2ea92 --- /dev/null +++ b/ohos/test_synchronized/lib/src/perf_test.dart @@ -0,0 +1,75 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:synchronized/synchronized.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; +import 'lock_factory.dart'; + +class PerfTestPage extends TestPage { + PerfTestPage(String title,{ Key? key}) : super(title: title, key: key) { + group('BasicLock', () { + run(BasicLockFactory()); + }); + group('ReentrantLock', () { + run(ReentrantLockFactory()); + }); + } + + void run(LockFactory factory) { + Lock newLock() => factory.newLock(); + final operationCount = 500000; + + test('$operationCount 次操作', () async { + final count = operationCount; + int j; + + var sw = Stopwatch(); + j = 0; + sw.start(); + for (var i = 0; i < count; i++) { + j += i; + } + print(' none ${sw.elapsed}'); + expect(j, count * (count - 1) / 2); + + sw = Stopwatch(); + j = 0; + sw.start(); + for (var i = 0; i < count; i++) { + await () async { + j += i; + }(); + } + print('await ${sw.elapsed}'); + expect(j, count * (count - 1) / 2); + + var lock = newLock(); + sw = Stopwatch(); + j = 0; + sw.start(); + for (var i = 0; i < count; i++) { + // ignore: unawaited_futures + lock.synchronized(() { + j += i; + }); + } + // final wait + await lock.synchronized(() => {}); + print('syncd ${sw.elapsed}'); + expect(j, count * (count - 1) / 2); + }); + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/lib/src/reentrant_lock_test.dart b/ohos/test_synchronized/lib/src/reentrant_lock_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..38c3ef51a51d6b43e26807ec7963321996174f5b --- /dev/null +++ b/ohos/test_synchronized/lib/src/reentrant_lock_test.dart @@ -0,0 +1,670 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/synchronized.dart'; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; +import 'package:synchronized/src/basic_lock.dart'; +import 'lock_factory.dart'; + +class ReentrantLockTestPage extends TestPage { + ReentrantLockTestPage(String title,{ Key? key}) : super(title: title, key: key) { + var lockFactory = ReentrantLockFactory(); + Lock newLock() => lockFactory.newLock(); + + group('ReentrantLock', () { + lockMain(lockFactory); + + test('可以重新锁定', () async { + bool? ok; + final lock = newLock(); + expect(lock.locked, false); + await lock.synchronized(() async { + expect(lock.locked, true); + await lock.synchronized(() { + expect(lock.locked, true); + ok = true; + }); + }); + expect(lock.locked, false); + expect(ok, true); + }); + + test('测试正在锁定中状态', () async { + var enterCompleter = Completer(); + var completer = Completer(); + final lock = newLock(); + expect(lock.locked, false); + expect(lock.inLock, false); + var future = lock.synchronized(() async { + enterCompleter.complete(); + expect(lock.locked, true); + expect(lock.inLock, true); + await completer.future; + }); + await enterCompleter.future; + expect(lock.locked, true); + expect(lock.inLock, false); + completer.complete(); + await future; + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('仅适用于可重新锁定的锁', () async { + final lock = newLock(); + + final list = []; + var future1 = lock.synchronized(() async { + list.add(1); + await lock.synchronized(() async { + await sleep(10); + list.add(2); + }); + list.add(3); + }); + var future2 = lock.synchronized(() { + list.add(4); + }); + await Future.wait([future1, future2]); + expect(list, [1, 2, 3, 4]); + }); + + test('锁定时内部修改存储内容', () async { + final lock = newLock(); + + expect( + await lock.synchronized(() async { + expect( + await lock.synchronized(() { + return 'inner'; + }), + 'inner'); + return 'outer'; + }), + 'outer'); + }); + + test('在锁定结束之后修改值', () async { + final lock = newLock(); + + final list = []; + // ignore: unawaited_futures + lock.synchronized(() async { + await sleep(1); + list.add(1); + + // This one should execute before + return lock.synchronized(() async { + await sleep(1); + list.add(2); + }); + }); + await lock.synchronized(() async { + list.add(3); + }); + expect(list, [1, 2, 3]); + }); + + test('不等待直接修改数据', () async { + final lock = newLock(); + final list = []; + // ignore: unawaited_futures + lock.synchronized(() { + list.add(1); + return lock.synchronized(() async { + await sleep(1); + list.add(3); + }); + }); + list.add(2); + await lock.synchronized(() async { + list.add(4); + }); + expect(list, [1, 2, 3, 4]); + }); + + test('两个锁同时锁定', () async { + var lock1 = newLock(); + var lock2 = newLock(); + + expect(Zone.current[lock1], null); + + bool? ok; + await lock1.synchronized(() async { + expect(Zone.current[lock1], Zone.current[lock1] !=null); + expect(Zone.current[lock2], null); + await lock2.synchronized(() async { + expect(Zone.current[lock2], Zone.current[lock2]!=null); + expect(Zone.current[lock1], Zone.current[lock1]==null); + + ok = true; + }); + }); + expect(ok, true); + }); + + group('error', () { + test('inner_throw', () async { + final lock = newLock(); + try { + await lock.synchronized(() async { + await lock.synchronized(() { + throw 'throwing'; + }); + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + await lock.synchronized(() {}); + }); + + test('inner_throw_async', () async { + final lock = newLock(); + try { + await lock.synchronized(() async { + await lock.synchronized(() async { + throw 'throwing'; + }); + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + await sleep(1); + }); + }); + + group('inner_lock', () { + test('超时锁定', () async { + final lock = newLock(); + await lock.synchronized(() async { + final completer = Completer(); + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) {} + expect(lock.locked, true); + completer.complete(); + await future; + }); + expect(lock.locked, false); + }); + + test('内部锁超时锁定', () async { + final lock = newLock(); + await lock.synchronized(() async { + await lock.synchronized(() async { + final completer = Completer(); + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) {} + expect(lock.locked, true); + completer.complete(); + await future; + }); + }); + expect(lock.locked, false); + }); + + test('延迟操作', () async { + final lock = newLock(); + var hasStateError = false; + var completer = Completer(); + await lock.synchronized(() { + sleep(1).then((_) async { + try { + await lock.synchronized(() {}); + } on StateError catch (_) { + hasStateError = true; + } finally { + completer.complete(); + } + }); + }); + expect(hasStateError, false); + await completer.future; + expect(hasStateError, true); + }); + }); + }); + } + + void lockMain(LockFactory lockFactory) { + Lock newLock() => lockFactory.newLock(); + + group('synchronized', () { + test('两个锁同时进行', () async { + var lock1 = newLock(); + var lock2 = newLock(); + + bool? ok; + await lock1.synchronized(() async { + await lock2.synchronized(() async { + expect(lock2.locked, true); + ok = true; + }); + }); + expect(ok, true); + }); + + test('锁定时操作list', () async { + final lock = newLock(); + final list = []; + final future1 = lock.synchronized(() async { + list.add(1); + }); + final future2 = lock.synchronized(() async { + await sleep(10); + list.add(2); + return 'text'; + }); + final future3 = lock.synchronized(() { + list.add(3); + return 1234; + }); + expect(list, [1]); + await Future.wait([future1, future2, future3]); + expect(await future1, null); + expect(await future2, 'text'); + expect(await future3, 1234); + expect(list, [1, 2, 3]); + }); + + test('排队修改值', () async { + final lock = newLock(); + final value1 = lock.synchronized(() async { + await sleep(1); + return 'value1'; + }); + expect(await lock.synchronized(() => 'value2'), 'value2'); + expect(await value1, 'value1'); + }); + + group('perf', () { + final operationCount = 10000; + + test('$operationCount 次操作', () async { + var count = operationCount; + int j; + + final sw1 = Stopwatch(); + j = 0; + sw1.start(); + for (var i = 0; i < count; i++) { + j += i; + } + sw1.stop(); + expect(j, count * (count - 1) / 2); + + final sw2 = Stopwatch(); + j = 0; + sw2.start(); + for (var i = 0; i < count; i++) { + await () async { + j += i; + }(); + } + sw2.stop(); + expect(j, count * (count - 1) / 2); + + var lock = newLock(); + final sw3 = Stopwatch(); + j = 0; + sw3.start(); + for (var i = 0; i < count; i++) { + // ignore: unawaited_futures + lock.synchronized(() { + j += i; + }); + } + // final wait + await lock.synchronized(() => {}); + expect(lock.locked, false); + sw3.stop(); + expect(j, count * (count - 1) / 2); + + final sw4 = Stopwatch(); + j = 0; + sw4.start(); + for (var i = 0; i < count; i++) { + await lock.synchronized(() async { + await Future.value(); + j += i; + }); + } + // final wait + expect(lock.locked, false); + sw4.stop(); + expect(j, count * (count - 1) / 2); + + print(' none ${sw1.elapsed}'); + print(' await ${sw2.elapsed}'); + print(' syncd ${sw3.elapsed}'); + print('asyncd ${sw4.elapsed}'); + }); + }); + + group('超时测试', () { + test('1_ms', () async { + final lock = newLock(); + final completer = Completer(); + final future = lock.synchronized(() async { + await completer.future; + }); + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.complete(); + await future; + }); + + test('100_ms', () async { + // var isNewTiming = await isDart2AsyncTiming(); + // hoping timint is ok... + final lock = newLock(); + + var ran1 = false; + var ran2 = false; + var ran3 = false; + var ran4 = false; + // hold for 5ms + // ignore: unawaited_futures + lock.synchronized(() async { + await sleep(1000); + }); + + try { + await lock.synchronized(() { + ran1 = true; + }, timeout: const Duration(milliseconds: 1)); + } on TimeoutException catch (_) {} + + try { + await lock.synchronized(() async { + await sleep(5000); + ran2 = true; + }, timeout: const Duration(milliseconds: 1)); + // fail('should fail'); + } on TimeoutException catch (_) {} + + try { + // ignore: unawaited_futures + lock.synchronized(() { + ran4 = true; + }, timeout: const Duration(milliseconds: 2000)); + } on TimeoutException catch (_) {} + + // waiting long enough + await lock.synchronized(() { + ran3 = true; + }, timeout: const Duration(milliseconds: 2000)); + + expect(ran1, false); + expect(ran2, false); + expect(ran3, true); + expect(ran4, true); + }); + + test('1_ms_with_error', () async { + var ok = false; + var okTimeout = false; + try { + final lock = newLock(); + final completer = Completer(); + unawaited(lock.synchronized(() async { + await completer.future; + }).catchError((e) {})); + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 1)); + fail('should fail'); + } on TimeoutException catch (_) {} + completer.completeError('error'); + // await future; + // await lock.synchronized(null, timeout: Duration(milliseconds: 1000)); + + // Make sure these block ran + await lock.synchronized(() { + ok = true; + }); + await lock.synchronized(() { + okTimeout = true; + }, timeout: const Duration(milliseconds: 1000)); + } catch (_) {} + expect(ok, true); + expect(okTimeout, true); + }); + }); + + group('error', () { + test('throw', () async { + final lock = newLock(); + try { + await lock.synchronized(() { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('queued_throw', () async { + final lock = newLock(); + + // delay so that it is queued + // ignore: unawaited_futures + lock.synchronized(() { + return sleep(1); + }); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + + var ok = false; + await lock.synchronized(() { + ok = true; + }); + expect(ok, true); + }); + + test('throw_async', () async { + final lock = newLock(); + try { + await lock.synchronized(() async { + throw 'throwing'; + }); + fail('should throw'); // ignore: dead_code + } catch (e) { + expect(e, false); + } + }); + }); + + group('immediacity', () { + test('同步获取值', () async { + var lock = newLock(); + int? value; + final future = lock.synchronized(() { + value = 1; + return Future.value().then((_) { + value = 2; + }); + }); + // A sync method is executed right away! + expect(value, 1); + await future; + expect(value, 2); + }); + + test('异步获取值', () async { + var lock = newLock(); + int? value; + final future = lock.synchronized(() async { + value = 1; + return Future.value().then((_) { + value = 2; + }); + }); + // A sync method is executed right away! + expect(value, 1); + + await future; + expect(value, 2); + }); + }); + + group('locked', () { + test('simple', () async { + // Make sure the lock state is made immediately + // when the function is not async + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() => {}); + expect(lock.locked, false); + await future; + expect(lock.locked, false); + }); + + test('simple_async', () async { + // Make sure the lock state is lazy for async method + var lock = newLock(); + expect(lock.locked, false); + final future = lock.synchronized(() async => {}); + expect(lock.locked, true); + await future; + expect(lock.locked, false); + }); + }); + group('locked_in_lock', () { + test('测试两个锁', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + + unawaited(lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + })); + + await lock.synchronized(() async { + await sleep(1); + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('simple', () async { + var lock = newLock(); + + expect(lock.locked, false); + expect(lock.inLock, false); + await lock.synchronized(() async { + expect(lock.locked, true); + expect(lock.inLock, true); + }); + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('locked', () async { + final lock = newLock(); + final completer = Completer(); + expect(lock.locked, false); + expect(lock.inLock, false); + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + if (lock is BasicLock) { + expect(lock.inLock, true); + } + completer.complete(); + await future; + expect(lock.locked, false); + expect(lock.inLock, false); + }); + + test('locked_with_timeout', () async { + final lock = newLock(); + final completer = Completer(); + + // Lock it forever + final future = lock.synchronized(() async { + await completer.future; + }); + expect(lock.locked, true); + + // Expect a time out exception + var hasTimeoutException = false; + try { + await lock.synchronized(() {}, timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) { + // Timeout exception expected + hasTimeoutException = true; + } + expect(hasTimeoutException, true); + expect(lock.locked, true); + // Release the forever waiting lock + completer.complete(); + await future; + expect(lock.locked, false); + + // Should succeed right away + await lock.synchronized(() {}, timeout: const Duration(seconds: 10)); + }); + }); + }); + } +} diff --git a/ohos/test_synchronized/lib/src/synchronized_impl_test.dart b/ohos/test_synchronized/lib/src/synchronized_impl_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..56419f966ae7ca9f2526ae6a8a1e0514b7187397 --- /dev/null +++ b/ohos/test_synchronized/lib/src/synchronized_impl_test.dart @@ -0,0 +1,148 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Copyright (c) 2016, Alexandre Roux Tekartik. All rights reserved. Use of this source code + +// is governed by a BSD-style license that can be found in the LICENSE file. + +import 'package:synchronized/src/basic_lock.dart'; +import 'package:synchronized/src/reentrant_lock.dart'; +import 'package:synchronized/src/utils.dart'; +import 'package:synchronized/synchronized.dart' as common; +import 'package:flutter/material.dart'; +import '../common/test_page.dart'; + +class SynchronizedImplTestPage extends TestPage { + SynchronizedImplTestPage(String title, {Key? key}) + : super(title: title, key: key) { + group('synchronized_impl', () { + group('BasicLock', () { + test('测试类型 type', () { + var lock = common.Lock(); + expect(lock, null); + }); + test('测试 toString', () { + var lock = common.Lock(); + expect('$lock', null); + expect('$lock', null); + }); + }); + + group('ReentrantLock', () { + test('测试创建锁后是否为空', () { + var lock = common.Lock(reentrant: true); + expect(lock, null); + }); + + test('测试 toString', () { + var lock = common.Lock(reentrant: true); + expect('$lock', null); + expect('$lock', null); + }); + + group('locked', () { + test('测试锁定时是否有等待操作', () async { + final lock = ReentrantLock(); + final completer = Completer(); + final innerCompleter = Completer(); + final future = lock.synchronized(() async { + await lock.synchronized(() async { + await sleep(1); + await innerCompleter.future; + }); + await completer.future; + }); + expect(lock.locked, true); + completer.complete(); + try { + await lock.synchronized(() {}, + timeout: const Duration(milliseconds: 100)); + fail('should fail'); + } on TimeoutException catch (_) {} + expect(lock.locked, true); + innerCompleter.complete(); + await future; + expect(lock.locked, false); + }); + }); + + group('inLock', () { + test('两个锁', () async { + final lock1 = ReentrantLock(); + final lock2 = ReentrantLock(); + final completer = Completer(); + final future = lock1.synchronized(() async { + expect(lock1.inLock, true); + expect(lock2.inLock, false); + await completer.future; + }); + expect(lock1.inLock, false); + completer.complete(); + await future; + }); + + test('锁定时查看值的变化', () async { + final lock = ReentrantLock(); + expect(lock.innerLocks.length, 1); + final future = lock.synchronized(() async { + expect(lock.inLock, true); + + expect(lock.innerLocks.length, 2); + + await lock.synchronized(() async { + expect(lock.innerLocks.length, 3); + expect(lock.inLock, true); + await sleep(10); + expect(lock.inLock, true); + expect(lock.innerLocks.length, 3); + }); + expect(lock.innerLocks.length, 2); + }); + // yes we are right away at level 3! + expect(lock.innerLocks.length, 3); + expect(lock.inLock, false); + await future; + expect(lock.innerLocks.length, 1); + expect(lock.inLock, false); + }); + + test('锁定时查看内部和外部的变化', () async { + final list = []; + final lock = ReentrantLock(); + final future = lock.synchronized(() async { + await sleep(10); + await lock.synchronized(() async { + await sleep(20); + list.add(1); + }); + }); + expect(lock.inLock, false); + final future2 = lock.synchronized(() async { + await sleep(10); + list.add(2); + }); + final future3 = sleep(20).whenComplete(() async { + await lock.synchronized(() async { + list.add(3); + }); + }); + await Future.wait([future, future2, future3]); + expect(list, [1, 2, 3]); + }); + }); + }); + }); + } +} diff --git a/ohos/test_synchronized/ohos/.gitignore b/ohos/test_synchronized/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_synchronized/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/AppScope/app.json5 b/ohos/test_synchronized/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..88d1517ac1d6cfaf7786b767c5ef7fa9e29b36c7 --- /dev/null +++ b/ohos/test_synchronized/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_synchronized", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_synchronized/ohos/AppScope/resources/base/element/string.json b/ohos/test_synchronized/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..858c0ee471d03a20dacad6e8bce2b476898cc847 --- /dev/null +++ b/ohos/test_synchronized/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_synchronized" + } + ] +} diff --git a/ohos/test_synchronized/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_synchronized/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_synchronized/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_synchronized/ohos/build-profile.json5 b/ohos/test_synchronized/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..33f3c0d2196b9c11d85f0d9ab496ed6598266cbc --- /dev/null +++ b/ohos/test_synchronized/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_synchronized.cer", + "storePassword": "0000001B88E4A8AEE72D6E26C0E9EAB09903EE1F70B913F1EDE93C9626E52DF823197E111EE09F3968350E", + "keyAlias": "debugKey", + "keyPassword": "0000001B11F4A4EF09B0D83BCE29CCE80E0193ED518169AD6649643C9590F627C72CC8A0772FC91D9B77A3", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_synchronized.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_synchronized.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_synchronized/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_synchronized/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_synchronized/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_synchronized/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_synchronized/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_synchronized/ohos/dependencies/rollup.tgz b/ohos/test_synchronized/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_synchronized/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_synchronized/ohos/dta/icudtl.dat b/ohos/test_synchronized/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_synchronized/ohos/dta/icudtl.dat differ diff --git a/ohos/test_synchronized/ohos/entry/.gitignore b/ohos/test_synchronized/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/build-profile.json5 b/ohos/test_synchronized/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/hvigorfile.ts b/ohos/test_synchronized/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_synchronized/ohos/entry/oh-package.json5 b/ohos/test_synchronized/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_synchronized/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_synchronized/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_synchronized/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_synchronized/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/module.json5 b/ohos/test_synchronized/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_synchronized/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_synchronized/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_synchronized/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3abf18c41c58c933308c244a875bf383856e103e --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]}] \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..2c72ec7ee9cc1d15ce7a90b54bdfaa944cf5b2d9 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..dd9b541623bc3d9eb67fa26060e0a7750cd8e8e8 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_synchronized/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_synchronized/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/module.json5 b/ohos/test_synchronized/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_synchronized/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_synchronized/ohos/har/flutter_embedding.har b/ohos/test_synchronized/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_synchronized/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_synchronized/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.10 b/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.9 b/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_synchronized/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_synchronized/ohos/har/libflutter.so.debug.10 b/ohos/test_synchronized/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_synchronized/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_synchronized/ohos/har/libflutter.so.release.10 b/ohos/test_synchronized/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_synchronized/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_synchronized/ohos/hvigor/hvigor-config.json5 b/ohos/test_synchronized/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_synchronized/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_synchronized/ohos/hvigor/hvigor-wrapper.js b/ohos/test_synchronized/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_synchronized/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/hvigorfile.ts b/ohos/test_synchronized/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_synchronized/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/hvigorw b/ohos/test_synchronized/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_synchronized/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_synchronized/ohos/hvigorw.bat b/ohos/test_synchronized/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_synchronized/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_synchronized/ohos/oh-package-lock.json5 b/ohos/test_synchronized/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_synchronized/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_synchronized/ohos/oh-package.json5 b/ohos/test_synchronized/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_synchronized/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_synchronized/pubspec.yaml b/ohos/test_synchronized/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..fa794ea0a47757682d789517c52f9d8691faa52e --- /dev/null +++ b/ohos/test_synchronized/pubspec.yaml @@ -0,0 +1,28 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_synchronized +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + synchronized: 3.1.0 +flutter: + uses-material-design: true \ No newline at end of file diff --git a/ohos/test_visibility_detector/.gitignore b/ohos/test_visibility_detector/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..24476c5d1eb55824c76d8b01a3965f94abad1ef8 --- /dev/null +++ b/ohos/test_visibility_detector/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/ohos/test_visibility_detector/.metadata b/ohos/test_visibility_detector/.metadata new file mode 100644 index 0000000000000000000000000000000000000000..7bfba2dfa9d13ee221986e80ce03c94cc93cc912 --- /dev/null +++ b/ohos/test_visibility_detector/.metadata @@ -0,0 +1,30 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled. + +version: + revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + channel: master + +project_type: app + +# Tracks metadata for the flutter migrate command +migration: + platforms: + - platform: root + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + - platform: ohos + create_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + base_revision: 0251c48f3356696dfeb79833b1cb00ea8717a982 + + # User provided section + + # List of Local paths (relative to this file) that should be + # ignored by the migrate tool. + # + # Files that are not part of the templates will be ignored by default. + unmanaged_files: + - 'lib/main.dart' + - 'ios/Runner.xcodeproj/project.pbxproj' diff --git a/ohos/test_visibility_detector/README.md b/ohos/test_visibility_detector/README.md new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/ohos/test_visibility_detector/analysis_options.yaml b/ohos/test_visibility_detector/analysis_options.yaml new file mode 100644 index 0000000000000000000000000000000000000000..6ddaee52a3c1b7a6ed51caf1e7e69037e53dc4ab --- /dev/null +++ b/ohos/test_visibility_detector/analysis_options.yaml @@ -0,0 +1,44 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. + +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml + +linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. + rules: + # avoid_print: false # Uncomment to disable the `avoid_print` rule + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/ohos/test_visibility_detector/lib/common/base_page.dart b/ohos/test_visibility_detector/lib/common/base_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..b177b5b1e64c7231175a3b0b9a6c0891c4190f1f --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/base_page.dart @@ -0,0 +1,55 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'main_item_widget.dart'; +import 'test_route.dart'; + +/// 全局静态数据存储 +abstract class GlobalData { + static String appName = ''; +} + +/// app基本首页 +class BasePage extends StatefulWidget { + const BasePage({required this.data}); + + final List data; + + @override + State createState() => _BasePageState(); +} + +class _BasePageState extends State { + int get _itemCount => widget.data.length; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Center( + child: Text(GlobalData.appName, textAlign: TextAlign.center)), + ), + body: + ListView.builder(itemBuilder: _itemBuilder, itemCount: _itemCount)); + } + + Widget _itemBuilder(BuildContext context, int index) { + return MainItemWidget(widget.data[index], (MainItem item) { + Navigator.push(context, MaterialPageRoute(builder: (content) => item.route)); + }); + } +} diff --git a/ohos/test_visibility_detector/lib/common/item_widget.dart b/ohos/test_visibility_detector/lib/common/item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..c819693a73244796d1bf5cf7bae12eb07503da2e --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/item_widget.dart @@ -0,0 +1,128 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_page.dart'; + +/// Item widget. +class ItemWidget extends StatefulWidget { + /// Item widget. + const ItemWidget( + {required this.item, required this.index, required this.getGroupRange, required this.runGroup, required this.onTap, this.summary, Key? key}) + : super(key: key); + + /// item summary. + final String? summary; + + /// item data. + final Item item; + + /// 当前下标 + final int index; + + /// 获取对应的组信息 + final GroupRange Function() getGroupRange; + + /// 获取对应的组信息 + final void Function(int start, int end) runGroup; + + /// Action when pressed (typically run). + final void Function(Item item) onTap; + + @override + ItemWidgetState createState() => ItemWidgetState(); +} + +class ItemWidgetState extends State { + @override + Widget build(BuildContext context) { + IconData? icon; + Color? color; + + switch (widget.item.state) { + case ItemState.none: + icon = Icons.arrow_forward_ios; + break; + case ItemState.running: + icon = Icons.more_horiz; + break; + case ItemState.success: + icon = Icons.check; + color = Colors.green; + break; + case ItemState.failure: + icon = Icons.close; + color = Colors.red; + break; + } + + final Widget listTile = ListTile( + leading: SizedBox( + child: IconButton( + icon: Icon(icon, color: color), + onPressed: null, + )), + title: Text(widget.item.name), + subtitle: widget.summary != null ? Text(widget.summary!) : null, + onTap: () { + widget.onTap(widget.item); + }); + + final data = widget.getGroupRange(); + + return Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + if (data.groupName.isNotEmpty && data.startIndex == widget.index) + GestureDetector( + onTap: () {}, + child: Container( + height: 35, + decoration: BoxDecoration(color: CupertinoColors.extraLightBackgroundGray), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded(child: Text( + '测试组: ${data.groupName}', + style: TextStyle(fontSize: 18), + overflow: TextOverflow.ellipsis, + )), + // FilledButton( + // onPressed: () => widget.runGroup(data.startIndex, data.startIndex), + // child: Text( + // '整组测试', + // style: TextStyle(fontSize: 16), + // )) + ], + ), + ), + ), + Container( + margin: data.groupName.isNotEmpty && data.startIndex == widget.index ? EdgeInsets.only(bottom: 10) : null, + decoration: BoxDecoration( + border: data.groupName.isNotEmpty && data.endIndex == widget.index ? Border(bottom: BorderSide(color: Colors.grey)) : null, + ), + child: Padding( + padding: data.groupName.isNotEmpty && data.startIndex <= widget.index && data.endIndex >= widget.index ? EdgeInsets.only(left: 35) : EdgeInsets.zero, + child: listTile, + ), + ) + ], + ); + } +} diff --git a/ohos/test_visibility_detector/lib/common/main_item_widget.dart b/ohos/test_visibility_detector/lib/common/main_item_widget.dart new file mode 100644 index 0000000000000000000000000000000000000000..e74bc192352277bded3cfe99cea44f59652eb61e --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/main_item_widget.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; + +import 'test_route.dart'; + +/// Main item widget. +class MainItemWidget extends StatefulWidget { + /// Main item widget. + const MainItemWidget(this.item, this.onTap, {Key? key}) : super(key: key); + + /// item data. + final MainItem item; + + /// onTap action (typically run or open). + final void Function(MainItem item) onTap; + + @override + MainItemWidgetState createState() => MainItemWidgetState(); +} + +class MainItemWidgetState extends State { + @override + Widget build(BuildContext context) { + return Container( + margin: const EdgeInsets.only(bottom: 10), + child: ListTile( + tileColor: CupertinoColors.extraLightBackgroundGray, + title: Text(widget.item.title), + onTap: _onTap), + ); + } + + void _onTap() { + widget.onTap(widget.item); + } +} diff --git a/ohos/test_visibility_detector/lib/common/test_model_app.dart b/ohos/test_visibility_detector/lib/common/test_model_app.dart new file mode 100644 index 0000000000000000000000000000000000000000..9248d4e6da17ff0cfb6f6144b0eaf29648c45fd9 --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/test_model_app.dart @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; + +import 'base_page.dart'; +import 'test_route.dart'; + +/// 基础app框架 +class TestModelApp extends StatefulWidget { + TestModelApp({super.key, required this.appName, required this.data}) { + GlobalData.appName = appName; + } + + /// 测试包名称 + final String appName; + + /// 路由数据 + final List data; + + @override + State createState() => TestModelState(); +} + +class TestModelState extends State { + @override + Widget build(BuildContext context) { + return MaterialApp( + title: widget.appName, + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.blue), + appBarTheme: const AppBarTheme(backgroundColor: Colors.blue), + primarySwatch: Colors.blue, + useMaterial3: true, + ), + home: BasePage(data: widget.data), + ); + } +} diff --git a/ohos/test_visibility_detector/lib/common/test_page.dart b/ohos/test_visibility_detector/lib/common/test_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..3fbbeb3cd4375bf7eab9daf885146ac568372cb8 --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/test_page.dart @@ -0,0 +1,334 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:async'; + +import 'package:flutter/material.dart'; + +import 'item_widget.dart'; + +List contentList = []; + +class Test { + /// Test definition. + Test(this.name, this.fn, {bool? solo, bool? skip}) + : solo = solo == true, + skip = skip == true; + + /// Only run this test. + final bool solo; + + /// Skip this test. + final bool skip; + + /// Test name. + String name; + + /// Test body. + FutureOr Function() fn; +} + +/// Item states. +enum ItemState { + /// test not run yet. + none, + + /// test is running. + running, + + /// test succeeded. + success, + + /// test fails. + failure +} + +/// Menu item. +class Item { + /// Menu item. + Item(this.name); + + /// Menu item state. + ItemState state = ItemState.running; + + /// Menu item name/ + String name; +} + +class TestLength { + TestLength(this.oldLength, this.newLength); + + int oldLength; + int newLength; +} + +class GroupRange { + GroupRange(this.groupName, this.startIndex, this.endIndex); + + String groupName; + int startIndex; + int endIndex; +} + +/// 基础测试页面 +class TestPage extends StatefulWidget { + /// Base test page. + TestPage({required this.title, Key? key}) : super(key: key); + + /// The title. + final String title; + + /// Test list. + final List tests = []; + + /// 保存group的范围信息 + final Map groupTitle = {}; + + /// define a test. + void test(String name, FutureOr Function() fn) { + tests.add(Test(name, fn)); + } + + /// define a group test. + void group(String name, FutureOr Function() fn) { + int oldLength = tests.length; + fn(); + + int newLength = tests.length - 1; + groupTitle.addAll({name: TestLength(oldLength, newLength)}); + } + + /// Thrown an exception + void fail([String? message]) { + throw Exception(message ?? 'should fail'); + } + + @override + TestPageState createState() => TestPageState(); +} + +/// Group. +mixin Group { + /// List of tests. + List get tests { + // TODO: implement tests + throw UnimplementedError(); + } + + bool? _hasSolo; + final _tests = []; + + /// Add a test. + void add(Test test) { + if (!test.skip) { + if (test.solo) { + if (_hasSolo != true) { + _hasSolo = true; + _tests.clear(); + } + _tests.add(test); + } else if (_hasSolo != true) { + _tests.add(test); + } + } + } + + /// true if it has solo or contains item with solo feature + bool? get hasSolo => _hasSolo; +} + +class TestPageState extends State with Group { + List items = []; + + Future _run() async { + if (!mounted) { + return null; + } + + setState(() { + items.clear(); + }); + _tests.clear(); + for (var test in widget.tests) { + add(test); + } + for (var test in _tests) { + var item = Item(test.name); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + + late int position; + setState(() { + position = items.length; + items.add(item); + }); + try { + await test.fn(); + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[position] = item; + }); + } + } + + Future _runTest(int index) async { + if (!mounted) { + return null; + } + + final test = _tests[index]; + + var item = items[index]; + setState(() { + contentList = []; + item.state = ItemState.running; + }); + contentList.add(Text(test.name, + style: const TextStyle(fontSize: 18, color: Colors.green))); + try { + await test.fn(); + + item = Item(test.name)..state = ItemState.success; + print('ohFlutter: ${test.name}, result: success'); + } catch (e, st) { + contentList.add(Text('$e, $st', + style: const TextStyle(fontSize: 18, color: Colors.red))); + print('ohFlutter: ${test.name}-error: $e, $st}'); + try { + print(st); + } catch (_) {} + item = Item(test.name)..state = ItemState.failure; + } + + if (!mounted) { + return null; + } + + setState(() { + items[index] = item; + }); + showAlertDialog(context); + } + + @override + void initState() { + super.initState(); + contentList = []; + _run(); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: Text(widget.title), + actions:[ + IconButton( + onPressed: () { + showAlertDialog(context); + }, + icon: const Icon(Icons.search_outlined), + ) + ] + ), + body: ListView(children: [ + ...items.asMap().keys.map((e) => _itemBuilder(context, e)).toList(), + ])); + } + + Widget _itemBuilder(BuildContext context, int index) { + final item = getItem(index); + return ItemWidget( + item: item, + index: index, + getGroupRange: () { + GroupRange data = GroupRange('', 0, 0); + widget.groupTitle.forEach((key, value) { + if (value.oldLength <= index && value.newLength >= index) { + data = GroupRange(key, value.oldLength, value.newLength); + } + }); + return data; + }, + runGroup: (start, end) async { + for (var i = start; i <= end; i++) { + await _runTest(i); + print('\n'); + } + }, + onTap: (Item item) { + _runTest(index); + } + ); + } + + Item getItem(int index) { + return items[index]; + } + + @override + List get tests => widget.tests; +} + +void expect(var testModel, var object) { + try { + testModel; + contentList.add(Text('$testModel')); + } catch (e) { + contentList.add(Text( + '$e', + style: const TextStyle(color: Colors.red), + )); + print(e.toString()); + } +} + +void showAlertDialog(BuildContext context) { + for (int i = 0; i < contentList.length; i++) { + print(contentList[i].data); + } + showDialog( + context: context, + barrierDismissible: false, + builder: (BuildContext context) { + return AlertDialog( + content: SingleChildScrollView( + child: Column( + children: contentList, + ), + ), + actions: [ + MaterialButton( + child: const Text('确定'), + onPressed: () { + Navigator.of(context).pop(); + }, + ), + ], + ); + }); +} diff --git a/ohos/test_visibility_detector/lib/common/test_route.dart b/ohos/test_visibility_detector/lib/common/test_route.dart new file mode 100644 index 0000000000000000000000000000000000000000..64478b233caa2d718c7c63b8477c0021406cd59a --- /dev/null +++ b/ohos/test_visibility_detector/lib/common/test_route.dart @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/cupertino.dart'; + +import 'base_page.dart'; + +class MainItem { + /// Main item. + MainItem(this.title, this.route); + + /// title. + String title; + + /// Page route. + Widget route; +} diff --git a/ohos/test_visibility_detector/lib/main.dart b/ohos/test_visibility_detector/lib/main.dart new file mode 100644 index 0000000000000000000000000000000000000000..edbe5e8d7445115e8a45e7db2ce591c14e5bceff --- /dev/null +++ b/ohos/test_visibility_detector/lib/main.dart @@ -0,0 +1,30 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/material.dart'; +import 'package:test_visibility_detector/src/visibility_detector_demo_page.dart'; +import 'package:test_visibility_detector/src/unit_test.dart'; + +import 'common/test_model_app.dart'; +import 'common/test_route.dart'; + +void main() { + final app = [ + MainItem('VisibilityDetectorDemoPage', VisibilityDetectorDemoPage()), + MainItem('CacheManagerTestPage', CacheManagerTestPage('CacheManagerTestPage')), + ]; + + runApp(TestModelApp(appName: 'visibility_detector', data: app)); +} diff --git a/ohos/test_visibility_detector/lib/src/unit_test.dart b/ohos/test_visibility_detector/lib/src/unit_test.dart new file mode 100644 index 0000000000000000000000000000000000000000..043c14c9770468eeb59f382aa262980dab5bebc7 --- /dev/null +++ b/ohos/test_visibility_detector/lib/src/unit_test.dart @@ -0,0 +1,81 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'package:flutter/widgets.dart'; +import 'package:visibility_detector/visibility_detector.dart'; +import '../common/test_page.dart'; + +void _expectVisibility(Rect widgetBounds, Rect clipRect, Rect expectedVisibleBounds, double expectedVisibleFraction) { + final info = VisibilityInfo.fromRects(key: UniqueKey(), widgetBounds: widgetBounds, clipRect: clipRect); + expect(info.size, widgetBounds.size); + expect(info.visibleBounds, expectedVisibleBounds); + expect(info.visibleFraction, expectedVisibleFraction); +} + +class CacheManagerTestPage extends TestPage { + CacheManagerTestPage(String title, {Key? key}) : super(title: title, key: key) { + const clipRect = Rect.fromLTWH(100, 200, 300, 400); + + group('VisibilityInfo', () { + test('计算不可见', () { + const widgetBounds = Rect.fromLTWH(15, 25, 10, 20); + const expectedVisibleBounds = Rect.zero; + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0); + }); + + test('计算完全可见', () { + const widgetBounds = Rect.fromLTWH(115, 225, 10, 20); + const expectedVisibleBounds = Rect.fromLTWH(0, 0, 10, 20); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 1); + }); + + test('计算部分可见(屏幕外1边)', () { + const widgetBounds = Rect.fromLTWH(115, 195, 10, 20); + const expectedVisibleBounds = Rect.fromLTWH(0, 5, 10, 15); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0.75); + }); + + test('计算部分可见(屏幕外有2条边)', () { + const widgetBounds = Rect.fromLTWH(99, 195, 10, 20); + const expectedVisibleBounds = Rect.fromLTWH(1, 5, 9, 15); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0.675); + }); + + test('计算部分可见(屏幕外有3条边)', () { + const widgetBounds = Rect.fromLTWH(99, 195, 500, 20); + const expectedVisibleBounds = Rect.fromLTWH(1, 5, 300, 15); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0.45); + }); + + test('计算部分可见(屏幕外有4条边)', () { + const widgetBounds = Rect.fromLTWH(99, 195, 500, 600); + const expectedVisibleBounds = Rect.fromLTWH(1, 5, 300, 400); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0.4); + }); + + test('将~0%可见性计算为0%', () { + const widgetBounds = Rect.fromLTWH(100, 599, 300, 400); + const expectedVisibleBounds = Rect.fromLTWH(0, 0, 300, 1); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 0); + }); + + test('将~ 100%可见性计算为100%', () { + const widgetBounds = Rect.fromLTWH(100, 200, 300, 399); + const expectedVisibleBounds = Rect.fromLTWH(0, 0, 300, 399); + _expectVisibility(widgetBounds, clipRect, expectedVisibleBounds, 1); + }); + }); + } +} diff --git a/ohos/test_visibility_detector/lib/src/visibility_detector_demo_page.dart b/ohos/test_visibility_detector/lib/src/visibility_detector_demo_page.dart new file mode 100644 index 0000000000000000000000000000000000000000..edeb9a324b119798f155225f1c03b62253c0de84 --- /dev/null +++ b/ohos/test_visibility_detector/lib/src/visibility_detector_demo_page.dart @@ -0,0 +1,609 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import 'dart:collection'; + +import 'package:flutter/material.dart'; +import 'package:visibility_detector/visibility_detector.dart'; + +const String title = 'VisibilityDetector Demo'; + +/// The width of each cell of our pseudo-table of [VisibilityDetector] widgets. +const double cellWidth = 200; + +//// The height of each cell of our pseudo-table. +const double cellHeight = 200; + +/// The external padding around the primary row/column of the pseudo-table. +const double externalCellPadding = 5; + +/// The internal padding for each cell of the pseudo-table. +const double _cellPadding = 10; + +/// The external padding around the widgets in the visibility report section. +const double _reportPadding = 5; + +/// The height of the visibility report. +const double _reportHeight = 200; + +/// The [Key] to the main [ListView] widget. +const mainListKey = Key('MainList'); + +const scaleButtonKey = Key('scaleButton'); + +Key secondaryScrollableKey(int primaryIndex) => ValueKey('secondary-$primaryIndex'); + +/// Returns the [Key] to the [VisibilityDetector] widget in each cell of the +/// pseudo-table. +Key cellKey(int row, int col) => Key('Cell-$row-$col'); + +/// Returns the [Key] to the content of the cell. +Key cellContentKey(int row, int col) => Key('Content-$row-$col'); + +/// A callback to be invoked by the [VisibilityDetector.onVisibilityChanged] +/// callback. We use the extra level of indirection to allow widget tests to +/// reuse this demo app with a different callback. +final visibilityListeners = []; + +/// Axis and growth direction of the table. +class Layout { + const Layout(this.mainAxis, this.secondaryAxis, {this.reverse = false}); + + final Axis mainAxis; + final Axis secondaryAxis; + + /// Reverse direction of the secondary axis. + final bool reverse; +} + +/// The main page [VisibilityDetectorDemo]. +class VisibilityDetectorDemoPage extends StatefulWidget { + VisibilityDetectorDemoPage({Key? key, this.useSlivers = false}) : super(key: key); + + final bool useSlivers; + + @override + VisibilityDetectorDemoPageState createState() => VisibilityDetectorDemoPageState(); +} + +class VisibilityDetectorDemoPageState extends State { + VisibilityDetectorDemoPageState(); + + var _layoutIndex = 0; + + /// Whether the pseudo-table should be shown. + bool _tableShown = true; + + /// Whether to use slivers. + bool _useSlivers = false; + + bool _useScale = false; + + /// The four layouts, that can be changed via pressing the Layout button. + static const _layouts = [ + Layout(Axis.vertical, Axis.horizontal, reverse: false), + Layout(Axis.vertical, Axis.horizontal, reverse: true), + Layout(Axis.horizontal, Axis.vertical, reverse: false), + Layout(Axis.horizontal, Axis.vertical, reverse: true), + ]; + + Layout get _layout => _layouts[_layoutIndex]; + + @override + void initState() { + super.initState(); + _useSlivers = widget.useSlivers; + } + + /// Toggles the visibility of the pseudo-table of [VisibilityDetector] + /// widgets. + void _toggleTable() { + setState(() { + _tableShown = !_tableShown; + }); + } + + /// Toggles the visibility of the pseudo-table of [VisibilityDetector] + /// widgets. + void _toggleScale() { + setState(() { + _useScale = !_useScale; + }); + } + + /// Toggles between the layouts. + void _toggleLayout() { + setState(() { + _layoutIndex = (_layoutIndex + 1) % _layouts.length; + }); + } + + /// Toggles between RenderBox and RenderSliver widgets. + void _toggleSlivers() { + setState(() { + _useSlivers = !_useSlivers; + }); + } + + @override + Widget build(BuildContext context) { + // Our pseudo-table of [VisibilityDetector] widgets. We want to scroll both + // vertically and horizontally, so we'll implement it as a [ListView] of + // [ListView]s. + final table = !_tableShown + ? null + : ClipRect( + child: Container( + width: _useScale ? 400 : null, + height: _useScale ? 300 : null, + child: ListView.builder( + key: mainListKey, + scrollDirection: _layout.mainAxis, + itemExtent: (_layout.mainAxis == Axis.vertical ? cellHeight : cellWidth) + 2 * externalCellPadding, + itemBuilder: (BuildContext context, int primaryIndex) { + return _useSlivers + ? SliverDemoPageSecondaryAxis( + key: secondaryScrollableKey(primaryIndex), + primaryIndex: primaryIndex, + secondaryAxis: _layout.secondaryAxis, + reverse: _layout.reverse, + useScale: _useScale, + ) + : DemoPageSecondaryAxis( + key: secondaryScrollableKey(primaryIndex), + primaryIndex: primaryIndex, + secondaryAxis: _layout.secondaryAxis, + reverse: _layout.reverse, + useScale: _useScale, + ); + }, + ), + ), + ); + + return Scaffold( + appBar: AppBar(title: const Text(title)), + floatingActionButton: Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + FloatingActionButton( + shape: const Border(), + onPressed: _toggleLayout, + heroTag: null, + child: Text('当前:${_layoutIndex == 0 ? '从左到右' : _layoutIndex == 1 ? '从右到左' : _layoutIndex == 2 ? '从上到下' : '从下到上'}'), + ), + const SizedBox(width: 8), + // FloatingActionButton( + // shape: const Border(), + // onPressed: _toggleSlivers, + // heroTag: null, + // child: _useSlivers ? const Text('RenderBox') : const Text('RenderSliver'), + // ), + // const SizedBox(width: 8), + FloatingActionButton( + shape: const Border(), + onPressed: _toggleTable, + heroTag: null, + child: _tableShown ? const Text('隐藏') : const Text('显示'), + ), + const SizedBox(width: 8), + FloatingActionButton( + key: scaleButtonKey, + shape: const Border(), + onPressed: _toggleScale, + heroTag: null, + child: _useScale ? const Text('铺满') : const Text('不铺满'), + ), + ], + ), + body: Column( + children: [ + _tableShown ? Expanded(child: table!) : const Spacer(), + VisibilityReport(title: '当前显示 (${_useSlivers ? "RenderSliver" : "RenderBox"})'), + ], + ), + ); + } +} + +/// A secondary axis for the pseudo-table of [VisibilityDetector] widgets. +class DemoPageSecondaryAxis extends StatelessWidget { + const DemoPageSecondaryAxis({ + Key? key, + required this.primaryIndex, + required this.secondaryAxis, + required this.reverse, + required this.useScale, + }) : super(key: key); + + final Axis secondaryAxis; + final int primaryIndex; + final bool reverse; + final bool useScale; + + @override + Widget build(BuildContext context) { + return ListView.builder( + scrollDirection: secondaryAxis, + reverse: reverse, + padding: const EdgeInsets.all(externalCellPadding), + itemBuilder: (BuildContext context, int secondaryIndex) { + return DemoPageCell( + primaryIndex: primaryIndex, + secondaryIndex: secondaryIndex, + useSlivers: false, + useScale: useScale, + ); + }, + ); + } +} + +/// A Secondary axis using sliver cell widgets. +class SliverDemoPageSecondaryAxis extends StatelessWidget { + const SliverDemoPageSecondaryAxis({ + Key? key, + required this.primaryIndex, + required this.secondaryAxis, + required this.reverse, + required this.useScale, + }) : super(key: key); + + final Axis secondaryAxis; + final int primaryIndex; + final bool reverse; + final bool useScale; + + @override + Widget build(BuildContext context) { + return Padding( + padding: secondaryAxis == Axis.horizontal + ? const EdgeInsets.symmetric(vertical: externalCellPadding) + : const EdgeInsets.symmetric(horizontal: externalCellPadding), + child: CustomScrollView( + scrollDirection: secondaryAxis, + reverse: reverse, + slivers: [ + SliverToBoxAdapter( + child: SizedBox( + width: externalCellPadding, + height: externalCellPadding, + ), + ), + // Sliver version renders up to 20 columns. + for (var secondaryIndex = 0; secondaryIndex < 20; secondaryIndex++) + DemoPageCell( + primaryIndex: primaryIndex, + secondaryIndex: secondaryIndex, + useSlivers: true, + useScale: useScale, + ), + SliverToBoxAdapter( + child: SizedBox( + width: externalCellPadding, + height: externalCellPadding, + ), + ), + ], + ), + ); + } +} + +/// An individual cell for the pseudo-table of [VisibilityDetector] widgets. +class DemoPageCell extends StatelessWidget { + DemoPageCell({ + Key? key, + required this.primaryIndex, + required this.secondaryIndex, + required this.useSlivers, + required this.useScale, + }) : _cellName = 'Item $primaryIndex-$secondaryIndex', + _backgroundColor = ((primaryIndex + secondaryIndex) % 2 == 0) ? Colors.pink[200] : Colors.yellow[200], + super(key: key); + + final int primaryIndex; + final int secondaryIndex; + final bool useSlivers; + final bool useScale; + + /// The text to show for the cell. + final String _cellName; + + final Color? _backgroundColor; + + /// [VisibilityDetector] callback for when the visibility of the widget + /// changes. Triggers the [visibilityListeners] callbacks. + void _handleVisibilityChanged(VisibilityInfo info) { + for (final listener in visibilityListeners) { + listener(RowColumn(primaryIndex, secondaryIndex), info); + } + } + + @override + Widget build(BuildContext context) { + final cell = Container( + key: cellContentKey(primaryIndex, secondaryIndex), + width: cellWidth, + decoration: BoxDecoration( + color: _backgroundColor, + ), + alignment: Alignment.center, + child: SizedBox( + width: cellWidth, + height: cellHeight, + child: Stack( + children: [ + Column( + mainAxisAlignment: MainAxisAlignment.start, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + mainAxisSize: MainAxisSize.max, + children: List.generate( + 10, + (index) => Expanded( + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration(color: Colors.green, border: Border.all(color: Colors.black, width: 0.5)), + child: Center(child: Text((index).toString())), + ), + )).toList()), + ...List.generate( + 9, + (index) => Expanded( + flex: 1, + child: Container( + width: 20, + height: 20, + decoration: BoxDecoration(color: Colors.green, border: Border.all(color: Colors.black, width: 0.5)), + child: Center(child: Text((index + 1).toString())), + ), + )).toList(), + ], + ), + Padding( + padding: const EdgeInsets.all(_cellPadding), + child: Container( + width: cellWidth, + height: cellHeight, + child: FittedBox( + fit: BoxFit.scaleDown, + child: Text( + _cellName, + style: TextStyle(fontSize: 16), + ), + ), + )) + ], + ), + ), + ); + + if (useSlivers) { + return SliverVisibilityDetector( + key: cellKey(primaryIndex, secondaryIndex), + onVisibilityChanged: _handleVisibilityChanged, + sliver: SliverToBoxAdapter(child: cell), + ); + } + + var visibilityDetector = VisibilityDetector( + key: cellKey(primaryIndex, secondaryIndex), + onVisibilityChanged: _handleVisibilityChanged, + child: cell, + ); + + if (useScale) { + return Transform.scale( + scale: 0.25, + child: Padding( + padding: const EdgeInsets.only(left: 100), + child: visibilityDetector, + ), + ); + } else { + return visibilityDetector; + } + } +} + +/// A widget that lists the reported visibility percentages of the +/// [VisibilityDetector] widgets on the page. +class VisibilityReport extends StatelessWidget { + const VisibilityReport({Key? key, required this.title}) : super(key: key); + + /// The text to use for the heading of the report. + final String title; + + @override + Widget build(BuildContext context) { + final headingTextStyle = Theme.of(context).textTheme.titleLarge?.copyWith(color: Colors.white); + + final heading = Container( + padding: const EdgeInsets.all(_reportPadding), + alignment: Alignment.centerLeft, + decoration: const BoxDecoration(color: Colors.black), + child: Text(title, style: headingTextStyle), + ); + + final grid = Container( + padding: const EdgeInsets.all(_reportPadding), + decoration: BoxDecoration(color: Colors.grey[300]), + child: const SizedBox( + height: _reportHeight, + child: VisibilityReportGrid(), + ), + ); + + return Column(children: [heading, grid]); + } +} + +/// The portion of [VisibilityReport] that shows data. +class VisibilityReportGrid extends StatefulWidget { + const VisibilityReportGrid({Key? key}) : super(key: key); + + @override + VisibilityReportGridState createState() => VisibilityReportGridState(); +} + +class VisibilityReportGridState extends State { + /// Maps [row, column] indices to the visibility percentage of the + /// corresponding [VisibilityDetector] widget. + final _visibilities = SplayTreeMap(); + + /// The [Text] widgets used to fill our [GridView]. + List? _reportItems; + + /// See [State.initState]. Adds a callback to [visibilityListeners] to update + /// the visibility report with the widget's visibility. + @override + void initState() { + super.initState(); + + visibilityListeners.add(_update); + assert(visibilityListeners.contains(_update)); + } + + @override + void dispose() { + visibilityListeners.remove(_update); + + super.dispose(); + } + + /// Callback added to [visibilityListeners] to update the state. + void _update(RowColumn rc, VisibilityInfo info) { + setState(() { + if (info.visibleFraction == 0) { + _visibilities.remove(rc); + } else { + _visibilities[rc] = info.visibleFraction; + } + + // Invalidate `_reportItems` so that we regenerate it lazily. + _reportItems = null; + }); + } + + /// Populates [_reportItems]. + List _generateReportItems() { + final entries = _visibilities.entries; + final items = []; + + for (final i in entries) { + final visiblePercentage = (i.value * 100).toStringAsFixed(1); + items.add(Text('${i.key}: $visiblePercentage%')); + } + + // It's easier to read cells down than across, so sort by columns instead of + // by rows. + final tailIndex = items.length - items.length ~/ 3; + final midIndex = tailIndex - tailIndex ~/ 2; + final head = items.getRange(0, midIndex); + final mid = items.getRange(midIndex, tailIndex); + final tail = items.getRange(tailIndex, items.length); + return collate([head, mid, tail]).toList(growable: false); + } + + @override + Widget build(BuildContext context) { + _reportItems ??= _generateReportItems(); + + return GridView.count( + crossAxisCount: 3, + childAspectRatio: 8, + padding: const EdgeInsets.all(5), + children: _reportItems!, + ); + } +} + +/// A class for storing a [row, column] pair. +class RowColumn extends Comparable { + RowColumn(this.row, this.column); + + final int row; + final int column; + + @override + bool operator ==(dynamic other) { + if (other is RowColumn) { + return row == other.row && column == other.column; + } + return false; + } + + @override + int get hashCode => Object.hash(row, column); + + /// See [Comparable.compareTo]. Sorts [RowColumn] objects in row-major order. + @override + int compareTo(RowColumn other) { + if (row < other.row) { + return -1; + } else if (row > other.row) { + return 1; + } + + if (column < other.column) { + return -1; + } else if (column > other.column) { + return 1; + } + + return 0; + } + + @override + String toString() { + return '[$row, $column]'; + } +} + +/// Returns an [Iterable] containing the nth element (if it exists) of every +/// [Iterable] in `iterables` in sequence. +/// +/// Unlike [zip](https://pub.dev/documentation/quiver/latest/quiver.iterables/zip.html), +/// returns a single sequence and continues until *all* [Iterable]s are +/// exhausted. +/// +/// For example, `collate([[1, 4, 7], [2, 5, 8, 9], [3, 6]])` would return a +/// sequence `1, 2, 3, 4, 5, 6, 7, 8, 9`. +@visibleForTesting +Iterable collate(Iterable> iterables) sync* { + final iterators = [for (final iterable in iterables) iterable.iterator]; + if (iterators.isEmpty) { + return; + } + + while (true) { + var exhaustedCount = 0; + for (final i in iterators) { + if (i.moveNext()) { + yield i.current; + continue; + } + + exhaustedCount += 1; + if (exhaustedCount == iterators.length) { + // All iterators are at their ends. + return; + } + } + } +} diff --git a/ohos/test_visibility_detector/ohos/.gitignore b/ohos/test_visibility_detector/ohos/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fbabf771011fe78f9919db0b1195ab6cadffc2b0 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/.gitignore @@ -0,0 +1,11 @@ +/node_modules +/oh_modules +/local.properties +/.idea +**/build +/.hvigor +.cxx +/.clangd +/.clang-format +/.clang-tidy +**/.test \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/AppScope/app.json5 b/ohos/test_visibility_detector/ohos/AppScope/app.json5 new file mode 100644 index 0000000000000000000000000000000000000000..2709d6d56704c1e74ebfbcf1af4411249547aba2 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/AppScope/app.json5 @@ -0,0 +1,10 @@ +{ + "app": { + "bundleName": "com.example.test_visibility_detector", + "vendor": "example", + "versionCode": 1000000, + "versionName": "1.0.0", + "icon": "$media:app_icon", + "label": "$string:app_name" + } +} diff --git a/ohos/test_visibility_detector/ohos/AppScope/resources/base/element/string.json b/ohos/test_visibility_detector/ohos/AppScope/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..61be45645195ab28c2dca4c72dc059dde6cf9dde --- /dev/null +++ b/ohos/test_visibility_detector/ohos/AppScope/resources/base/element/string.json @@ -0,0 +1,8 @@ +{ + "string": [ + { + "name": "app_name", + "value": "test_visibility_detector" + } + ] +} diff --git a/ohos/test_visibility_detector/ohos/AppScope/resources/base/media/app_icon.png b/ohos/test_visibility_detector/ohos/AppScope/resources/base/media/app_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_visibility_detector/ohos/AppScope/resources/base/media/app_icon.png differ diff --git a/ohos/test_visibility_detector/ohos/build-profile.json5 b/ohos/test_visibility_detector/ohos/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..04b86bb4b7acaf578d0528328ff97f4b1c5a54ba --- /dev/null +++ b/ohos/test_visibility_detector/ohos/build-profile.json5 @@ -0,0 +1,56 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "app": { + "signingConfigs": [ + { + "name": "default", + "material": { + "certpath": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_visibility_detector.cer", + "storePassword": "0000001BC0F4B61664A417402DE20E3170D2FDDF126C5DBF9BFC4E0839CD6E6423402FC6F1E7D57CEE8E7C", + "keyAlias": "debugKey", + "keyPassword": "0000001B79D0C50A2D5DC3FE7956B0397C3EEE7628C44C1967895B92A7C8DA86AF57154505432F5AA62E3E", + "profile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_visibility_detector.p7b", + "signAlg": "SHA256withECDSA", + "storeFile": "C:\\Users\\hched\\.ohos\\config\\openharmony\\auto_ohos_default_ohos_com.example.test_visibility_detector.p12" + } + } + ], + "products": [ + { + "name": "default", + "signingConfig": "default", + "compileSdkVersion": "4.0.0(10)", + "compatibleSdkVersion": "4.0.0(10)", + "runtimeOS": "HarmonyOS", + } + ] + }, + "modules": [ + { + "name": "entry", + "srcPath": "./entry", + "targets": [ + { + "name": "default", + "applyToProducts": [ + "default" + ] + } + ] + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/dependencies/hvigor-2.3.0-s.tgz b/ohos/test_visibility_detector/ohos/dependencies/hvigor-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..34029f16ff4dcdd4931f187a618d35d2d8641c88 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/dependencies/hvigor-2.3.0-s.tgz differ diff --git a/ohos/test_visibility_detector/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz b/ohos/test_visibility_detector/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz new file mode 100644 index 0000000000000000000000000000000000000000..8e028e66b8d9dd720787fe2b0ae340d0f933877d Binary files /dev/null and b/ohos/test_visibility_detector/ohos/dependencies/hvigor-ohos-plugin-2.3.0-s.tgz differ diff --git a/ohos/test_visibility_detector/ohos/dependencies/rollup.tgz b/ohos/test_visibility_detector/ohos/dependencies/rollup.tgz new file mode 100644 index 0000000000000000000000000000000000000000..4d5d24f65ce03f6ac01d019209ca669d8eb8369a Binary files /dev/null and b/ohos/test_visibility_detector/ohos/dependencies/rollup.tgz differ diff --git a/ohos/test_visibility_detector/ohos/dta/icudtl.dat b/ohos/test_visibility_detector/ohos/dta/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/dta/icudtl.dat differ diff --git a/ohos/test_visibility_detector/ohos/entry/.gitignore b/ohos/test_visibility_detector/ohos/entry/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..2795a1c5b1fe53659dd1b71d90ba0592eaf7e043 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/.gitignore @@ -0,0 +1,7 @@ + +/node_modules +/oh_modules +/.preview +/build +/.cxx +/.test \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/build-profile.json5 b/ohos/test_visibility_detector/ohos/entry/build-profile.json5 new file mode 100644 index 0000000000000000000000000000000000000000..633d360fbc91a3186a23b66ab71b27e5618944cb --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/build-profile.json5 @@ -0,0 +1,29 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "apiType": 'stageMode', + "buildOption": { + }, + "targets": [ + { + "name": "default", + "runtimeOS": "HarmonyOS" + }, + { + "name": "ohosTest", + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/hvigorfile.ts b/ohos/test_visibility_detector/ohos/entry/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..894fc15c6b793f085e6c8506e43d719af658e8ff --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { hapTasks } from '@ohos/hvigor-ohos-plugin'; diff --git a/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libc++_shared.so b/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libc++_shared.so new file mode 100644 index 0000000000000000000000000000000000000000..831c9353702073d45889352a4dafb93103d67d20 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libc++_shared.so differ diff --git a/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libflutter.so b/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libflutter.so new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/libs/arm64-v8a/libflutter.so differ diff --git a/ohos/test_visibility_detector/ohos/entry/oh-package.json5 b/ohos/test_visibility_detector/ohos/entry/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..634457dbefa01335f0ebf7998689752b00a1332b --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": {}, + "author": "", + "name": "entry", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": { + "@ohos/flutter_ohos": "file:../har/flutter_embedding.har" + } +} diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/ohos/test_visibility_detector/ohos/entry/src/main/ets/entryability/EntryAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..321a4eeaacd7b8079a876e25c4dafd498e4d9fb9 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import { FlutterAbility } from '@ohos/flutter_ohos' + +export default class EntryAbility extends FlutterAbility { + onFlutterEngineReady(): void { + super.onFlutterEngineReady() + } +} diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/ets/pages/Index.ets b/ohos/test_visibility_detector/ohos/entry/src/main/ets/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..b53a20c437e96d195487b281e5e95402ea6cb97d --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/ets/pages/Index.ets @@ -0,0 +1,36 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import common from '@ohos.app.ability.common'; +import { FlutterPage } from '@ohos/flutter_ohos' + +const EVENT_BACK_PRESS = 'EVENT_BACK_PRESS' + +@Entry +@Component +struct Index { + private context = getContext(this) as common.UIAbilityContext + + build() { + Column() { + FlutterPage() + } + } + + onBackPress(): boolean { + this.context.eventHub.emit(EVENT_BACK_PRESS) + return true + } +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/module.json5 b/ohos/test_visibility_detector/ohos/entry/src/main/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..7bbf78b18f39991b1404061c7437538c7d532bb7 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/module.json5 @@ -0,0 +1,53 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +{ + "module": { + "name": "entry", + "type": "entry", + "description": "$string:module_desc", + "mainElement": "EntryAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:main_pages", + "abilities": [ + { + "name": "EntryAbility", + "srcEntry": "./ets/entryability/EntryAbility.ets", + "description": "$string:EntryAbility_desc", + "icon": "$media:icon", + "label": "$string:EntryAbility_label", + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "exported": true, + "skills": [ + { + "entities": [ + "entity.system.home" + ], + "actions": [ + "action.system.home" + ] + } + ] + } + ], + "requestPermissions": [ + {"name" : "ohos.permission.INTERNET"}, + ] + } +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/color.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/string.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/media/icon.png b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/media/icon.png differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/profile/main_pages.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/profile/main_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/base/profile/main_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "pages/Index" + ] +} diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/en_US/element/string.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/en_US/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..f94595515a99e0c828807e243494f57f09251930 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/en_US/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "module description" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..9e26dfeeb6e641a33dae4961196235bdb965b21b --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/AssetManifest.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json new file mode 100644 index 0000000000000000000000000000000000000000..3abf18c41c58c933308c244a875bf383856e103e --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/FontManifest.json @@ -0,0 +1 @@ +[{"family":"MaterialIcons","fonts":[{"asset":"fonts/MaterialIcons-Regular.otf"}]}] \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z new file mode 100644 index 0000000000000000000000000000000000000000..2a306a355d2ad70c21747d0247682a5eef18192e Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/NOTICES.Z differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf new file mode 100644 index 0000000000000000000000000000000000000000..8c99266130a89547b4344f47e08aacad473b14e0 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/fonts/MaterialIcons-Regular.otf differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat new file mode 100644 index 0000000000000000000000000000000000000000..d1f10917ab52e3ebd251abd7f5377d7196b80d67 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/icudtl.dat differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..d9970784bda967bbac6e63f12be60dabb5740946 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/isolate_snapshot_data differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin new file mode 100644 index 0000000000000000000000000000000000000000..7009c47206e3b383edf1489122752249534ff5cf Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/kernel_blob.bin differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag new file mode 100644 index 0000000000000000000000000000000000000000..0bb5a14a220d223adde1e69eb1959332d6bd08c7 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/shaders/ink_sparkle.frag differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data new file mode 100644 index 0000000000000000000000000000000000000000..6576876848db8f3f833bebb14de058ce02c9334e Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/main/resources/rawfile/flutter_assets/vm_snapshot_data differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/main/resources/zh_CN/element/string.json b/ohos/test_visibility_detector/ohos/entry/src/main/resources/zh_CN/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..597ecf95e61d7e30367c22fe2f8638008361b044 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/main/resources/zh_CN/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_desc", + "value": "模块描述" + }, + { + "name": "EntryAbility_desc", + "value": "description" + }, + { + "name": "EntryAbility_label", + "value": "label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/Ability.test.ets b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/Ability.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..25d4c71ff3cd584f5d64f6f8c0ac864928c234c4 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/Ability.test.ets @@ -0,0 +1,50 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium' + +export default function abilityTest() { + describe('ActsAbilityTest', function () { + // Defines a test suite. Two parameters are supported: test suite name and test suite function. + beforeAll(function () { + // Presets an action, which is performed only once before all test cases of the test suite start. + // This API supports only one parameter: preset action function. + }) + beforeEach(function () { + // Presets an action, which is performed before each unit test case starts. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: preset action function. + }) + afterEach(function () { + // Presets a clear action, which is performed after each unit test case ends. + // The number of execution times is the same as the number of test cases defined by **it**. + // This API supports only one parameter: clear action function. + }) + afterAll(function () { + // Presets a clear action, which is performed after all test cases of the test suite end. + // This API supports only one parameter: clear action function. + }) + it('assertContain',0, function () { + // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function. + hilog.info(0x0000, 'testTag', '%{public}s', 'it begin'); + let a = 'abc' + let b = 'b' + // Defines a variety of assertion methods, which are used to declare expected boolean conditions. + expect(a).assertContain(b) + expect(a).assertEqual(a) + }) + }) +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/List.test.ets b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/List.test.ets new file mode 100644 index 0000000000000000000000000000000000000000..f4140030e65d20df6af30a6bf51e464dea8f8aa6 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/test/List.test.ets @@ -0,0 +1,20 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import abilityTest from './Ability.test' + +export default function testsuite() { + abilityTest() +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets new file mode 100644 index 0000000000000000000000000000000000000000..4ca645e6013cfce8e7dbb728313cb8840c4da660 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/TestAbility.ets @@ -0,0 +1,63 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import UIAbility from '@ohos.app.ability.UIAbility'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; +import hilog from '@ohos.hilog'; +import { Hypium } from '@ohos/hypium'; +import testsuite from '../test/List.test'; +import window from '@ohos.window'; + +export default class TestAbility extends UIAbility { + onCreate(want, launchParam) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onCreate'); + hilog.info(0x0000, 'testTag', '%{public}s', 'want param:' + JSON.stringify(want) ?? ''); + hilog.info(0x0000, 'testTag', '%{public}s', 'launchParam:'+ JSON.stringify(launchParam) ?? ''); + var abilityDelegator: any + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var abilityDelegatorArguments: any + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + hilog.info(0x0000, 'testTag', '%{public}s', 'start run testcase!!!'); + Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite) + } + + onDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onDestroy'); + } + + onWindowStageCreate(windowStage: window.WindowStage) { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageCreate'); + windowStage.loadContent('testability/pages/Index', (err, data) => { + if (err.code) { + hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? ''); + return; + } + hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', + JSON.stringify(data) ?? ''); + }); + } + + onWindowStageDestroy() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onWindowStageDestroy'); + } + + onForeground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onForeground'); + } + + onBackground() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility onBackground'); + } +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets new file mode 100644 index 0000000000000000000000000000000000000000..cef0447cd2f137ef82d223ead2e156808878ab90 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testability/pages/Index.ets @@ -0,0 +1,49 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; + +@Entry +@Component +struct Index { + aboutToAppear() { + hilog.info(0x0000, 'testTag', '%{public}s', 'TestAbility index aboutToAppear'); + } + @State message: string = 'Hello World' + build() { + Row() { + Column() { + Text(this.message) + .fontSize(50) + .fontWeight(FontWeight.Bold) + Button() { + Text('next page') + .fontSize(20) + .fontWeight(FontWeight.Bold) + }.type(ButtonType.Capsule) + .margin({ + top: 20 + }) + .backgroundColor('#0D9FFB') + .width('35%') + .height('5%') + .onClick(()=>{ + }) + } + .width('100%') + } + .height('100%') + } + } \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts new file mode 100644 index 0000000000000000000000000000000000000000..1def08f2e9dcbfa3454a07b7a3b82b173bb90d02 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/ets/testrunner/OpenHarmonyTestRunner.ts @@ -0,0 +1,64 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +import hilog from '@ohos.hilog'; +import TestRunner from '@ohos.application.testRunner'; +import AbilityDelegatorRegistry from '@ohos.app.ability.abilityDelegatorRegistry'; + +var abilityDelegator = undefined +var abilityDelegatorArguments = undefined + +async function onAbilityCreateCallback() { + hilog.info(0x0000, 'testTag', '%{public}s', 'onAbilityCreateCallback'); +} + +async function addAbilityMonitorCallback(err: any) { + hilog.info(0x0000, 'testTag', 'addAbilityMonitorCallback : %{public}s', JSON.stringify(err) ?? ''); +} + +export default class OpenHarmonyTestRunner implements TestRunner { + constructor() { + } + + onPrepare() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner OnPrepare '); + } + + async onRun() { + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun run'); + abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments() + abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator() + var testAbilityName = abilityDelegatorArguments.bundleName + '.TestAbility' + let lMonitor = { + abilityName: testAbilityName, + onAbilityCreate: onAbilityCreateCallback, + }; + abilityDelegator.addAbilityMonitor(lMonitor, addAbilityMonitorCallback) + var cmd = 'aa start -d 0 -a TestAbility' + ' -b ' + abilityDelegatorArguments.bundleName + var debug = abilityDelegatorArguments.parameters['-D'] + if (debug == 'true') + { + cmd += ' -D' + } + hilog.info(0x0000, 'testTag', 'cmd : %{public}s', cmd); + abilityDelegator.executeShellCommand(cmd, + (err: any, d: any) => { + hilog.info(0x0000, 'testTag', 'executeShellCommand : err : %{public}s', JSON.stringify(err) ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.stdResult ?? ''); + hilog.info(0x0000, 'testTag', 'executeShellCommand : data : %{public}s', d.exitCode ?? ''); + }) + hilog.info(0x0000, 'testTag', '%{public}s', 'OpenHarmonyTestRunner onRun end'); + } +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/module.json5 b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/module.json5 new file mode 100644 index 0000000000000000000000000000000000000000..fab77ce2e0c61e3ad010bab5b27ccbd15f9a8c96 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/module.json5 @@ -0,0 +1,51 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "module": { + "name": "entry_test", + "type": "feature", + "description": "$string:module_test_desc", + "mainElement": "TestAbility", + "deviceTypes": [ + "phone" + ], + "deliveryWithInstall": true, + "installationFree": false, + "pages": "$profile:test_pages", + "abilities": [ + { + "name": "TestAbility", + "srcEntry": "./ets/testability/TestAbility.ets", + "description": "$string:TestAbility_desc", + "icon": "$media:icon", + "label": "$string:TestAbility_label", + "exported": true, + "startWindowIcon": "$media:icon", + "startWindowBackground": "$color:start_window_background", + "skills": [ + { + "actions": [ + "action.system.home" + ], + "entities": [ + "entity.system.home" + ] + } + ] + } + ] + } +} diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/color.json b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/color.json new file mode 100644 index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/color.json @@ -0,0 +1,8 @@ +{ + "color": [ + { + "name": "start_window_background", + "value": "#FFFFFF" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/string.json b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/string.json new file mode 100644 index 0000000000000000000000000000000000000000..65d8fa5a7cf54aa3943dcd0214f58d1771bc1f6c --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/element/string.json @@ -0,0 +1,16 @@ +{ + "string": [ + { + "name": "module_test_desc", + "value": "test ability description" + }, + { + "name": "TestAbility_desc", + "value": "the test ability" + }, + { + "name": "TestAbility_label", + "value": "test label" + } + ] +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/media/icon.png b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/media/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c Binary files /dev/null and b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/media/icon.png differ diff --git a/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json new file mode 100644 index 0000000000000000000000000000000000000000..b7e7343cacb32ce982a45e76daad86e435e054fe --- /dev/null +++ b/ohos/test_visibility_detector/ohos/entry/src/ohosTest/resources/base/profile/test_pages.json @@ -0,0 +1,5 @@ +{ + "src": [ + "testability/pages/Index" + ] +} diff --git a/ohos/test_visibility_detector/ohos/har/flutter_embedding.har b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har differ diff --git a/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.10 b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..d8e07ca297de2100ce605f8af1126daf6eeb5d8f Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.10 differ diff --git a/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.9 b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.9 new file mode 100644 index 0000000000000000000000000000000000000000..f0df4ca0064821178bf4254b16e8d23d873827da Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.debug.9 differ diff --git a/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.10 b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..da9b320a09600f678975b827160441e46144bf08 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.10 differ diff --git a/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.9 b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.9 new file mode 100644 index 0000000000000000000000000000000000000000..ba52754a80826e5614438b3faf931ed2f487eaab Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/flutter_embedding.har.release.9 differ diff --git a/ohos/test_visibility_detector/ohos/har/libflutter.so.debug.10 b/ohos/test_visibility_detector/ohos/har/libflutter.so.debug.10 new file mode 100644 index 0000000000000000000000000000000000000000..8ff0d04141a776e448478791df1e2a1c3aa7c5c4 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/libflutter.so.debug.10 differ diff --git a/ohos/test_visibility_detector/ohos/har/libflutter.so.release.10 b/ohos/test_visibility_detector/ohos/har/libflutter.so.release.10 new file mode 100644 index 0000000000000000000000000000000000000000..7cdf26180489e807496f02cd4736425b4ad42845 Binary files /dev/null and b/ohos/test_visibility_detector/ohos/har/libflutter.so.release.10 differ diff --git a/ohos/test_visibility_detector/ohos/hvigor/hvigor-config.json5 b/ohos/test_visibility_detector/ohos/hvigor/hvigor-config.json5 new file mode 100644 index 0000000000000000000000000000000000000000..e098cf378247ee524ee9ba26298b1f8093a18ea1 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/hvigor/hvigor-config.json5 @@ -0,0 +1,22 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +{ + "hvigorVersion": "file:../dependencies/hvigor-2.3.0-s.tgz", + "dependencies": { + "@ohos/hvigor-ohos-plugin": "file:../dependencies/hvigor-ohos-plugin-2.3.0-s.tgz", + "rollup": "file:../dependencies/rollup.tgz", + } +} diff --git a/ohos/test_visibility_detector/ohos/hvigor/hvigor-wrapper.js b/ohos/test_visibility_detector/ohos/hvigor/hvigor-wrapper.js new file mode 100644 index 0000000000000000000000000000000000000000..994f22987bd0739b9faa07c966b066c2d9218602 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/hvigor/hvigor-wrapper.js @@ -0,0 +1,2 @@ +"use strict";var e=require("fs"),t=require("path"),n=require("os"),r=require("crypto"),u=require("child_process"),o=require("constants"),i=require("stream"),s=require("util"),c=require("assert"),a=require("tty"),l=require("zlib"),f=require("net");function d(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var D=d(e),p=d(t),E=d(n),m=d(r),h=d(u),y=d(o),C=d(i),F=d(s),g=d(c),A=d(a),v=d(l),S=d(f),w="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O={},b={},_={},B=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(_,"__esModule",{value:!0}),_.isMac=_.isLinux=_.isWindows=void 0;const P=B(E.default),k="Windows_NT",x="Linux",N="Darwin";_.isWindows=function(){return P.default.type()===k},_.isLinux=function(){return P.default.type()===x},_.isMac=function(){return P.default.type()===N};var I={},T=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),R=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),M=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&T(t,e,n);return R(t,e),t};Object.defineProperty(I,"__esModule",{value:!0}),I.hash=void 0;const L=M(m.default);I.hash=function(e,t="md5"){return L.createHash(t).update(e,"utf-8").digest("hex")},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r};Object.defineProperty(e,"__esModule",{value:!0}),e.HVIGOR_BOOT_JS_FILE_PATH=e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=e.HVIGOR_PROJECT_DEPENDENCIES_HOME=e.HVIGOR_PROJECT_WRAPPER_HOME=e.HVIGOR_PROJECT_NAME=e.HVIGOR_PROJECT_ROOT_DIR=e.HVIGOR_PROJECT_CACHES_HOME=e.HVIGOR_PNPM_STORE_PATH=e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=e.HVIGOR_WRAPPER_TOOLS_HOME=e.HVIGOR_USER_HOME=e.DEFAULT_PACKAGE_JSON=e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME=e.PNPM=e.HVIGOR=e.NPM_TOOL=e.PNPM_TOOL=e.HVIGOR_ENGINE_PACKAGE_NAME=void 0;const u=r(p.default),o=r(E.default),i=_,s=I;e.HVIGOR_ENGINE_PACKAGE_NAME="@ohos/hvigor",e.PNPM_TOOL=(0,i.isWindows)()?"pnpm.cmd":"pnpm",e.NPM_TOOL=(0,i.isWindows)()?"npm.cmd":"npm",e.HVIGOR="hvigor",e.PNPM="pnpm",e.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME="hvigor-config.json5",e.DEFAULT_PACKAGE_JSON="package.json",e.HVIGOR_USER_HOME=u.resolve(o.homedir(),".hvigor"),e.HVIGOR_WRAPPER_TOOLS_HOME=u.resolve(e.HVIGOR_USER_HOME,"wrapper","tools"),e.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH=u.resolve(e.HVIGOR_WRAPPER_TOOLS_HOME,"node_modules",".bin",e.PNPM_TOOL),e.HVIGOR_PNPM_STORE_PATH=u.resolve(e.HVIGOR_USER_HOME,"caches"),e.HVIGOR_PROJECT_CACHES_HOME=u.resolve(e.HVIGOR_USER_HOME,"project_caches"),e.HVIGOR_PROJECT_ROOT_DIR=process.cwd(),e.HVIGOR_PROJECT_NAME=u.basename((0,s.hash)(e.HVIGOR_PROJECT_ROOT_DIR)),e.HVIGOR_PROJECT_WRAPPER_HOME=u.resolve(e.HVIGOR_PROJECT_ROOT_DIR,e.HVIGOR),e.HVIGOR_PROJECT_DEPENDENCIES_HOME=u.resolve(e.HVIGOR_PROJECT_CACHES_HOME,e.HVIGOR_PROJECT_NAME,"workspace"),e.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,e.DEFAULT_PACKAGE_JSON),e.HVIGOR_BOOT_JS_FILE_PATH=u.resolve(e.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js")}(b);var j={},$={};Object.defineProperty($,"__esModule",{value:!0}),$.logInfoPrintConsole=$.logErrorAndExit=void 0,$.logErrorAndExit=function(e){e instanceof Error?console.error(e.message):console.error(e),process.exit(-1)},$.logInfoPrintConsole=function(e){console.log(e)};var H=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),J=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),G=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&H(t,e,n);return J(t,e),t},V=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(j,"__esModule",{value:!0}),j.isFileExists=j.offlinePluginConversion=j.executeCommand=j.getNpmPath=j.hasNpmPackInPaths=void 0;const U=h.default,W=G(p.default),z=b,K=$,q=V(D.default);j.hasNpmPackInPaths=function(e,t){try{return require.resolve(e,{paths:[...t]}),!0}catch(e){return!1}},j.getNpmPath=function(){const e=process.execPath;return W.join(W.dirname(e),z.NPM_TOOL)},j.executeCommand=function(e,t,n){0!==(0,U.spawnSync)(e,t,n).status&&(0,K.logErrorAndExit)(`Error: ${e} ${t} execute failed.See above for details.`)},j.offlinePluginConversion=function(e,t){return t.startsWith("file:")||t.endsWith(".tgz")?W.resolve(e,z.HVIGOR,t.replace("file:","")):t},j.isFileExists=function(e){return q.default.existsSync(e)&&q.default.statSync(e).isFile()},function(e){var t=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),n=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var r={};if(null!=e)for(var u in e)"default"!==u&&Object.prototype.hasOwnProperty.call(e,u)&&t(r,e,u);return n(r,e),r},u=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(e,"__esModule",{value:!0}),e.executeInstallPnpm=e.isPnpmAvailable=e.environmentHandler=e.checkNpmConifg=e.PNPM_VERSION=void 0;const o=r(D.default),i=b,s=j,c=r(p.default),a=$,l=h.default,f=u(E.default);e.PNPM_VERSION="7.30.0",e.checkNpmConifg=function(){const e=c.resolve(i.HVIGOR_PROJECT_ROOT_DIR,".npmrc"),t=c.resolve(f.default.homedir(),".npmrc");if((0,s.isFileExists)(e)||(0,s.isFileExists)(t))return;const n=(0,s.getNpmPath)(),r=(0,l.spawnSync)(n,["config","get","prefix"],{cwd:i.HVIGOR_PROJECT_ROOT_DIR});if(0!==r.status||!r.stdout)return void(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.");const u=c.resolve(`${r.stdout}`.replace(/[\r\n]/gi,""),".npmrc");(0,s.isFileExists)(u)||(0,a.logErrorAndExit)("Error: The hvigor depends on the npmrc file. Configure the npmrc file first.")},e.environmentHandler=function(){process.env["npm_config_update-notifier"]="false"},e.isPnpmAvailable=function(){return!!o.existsSync(i.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH)&&(0,s.hasNpmPackInPaths)("pnpm",[i.HVIGOR_WRAPPER_TOOLS_HOME])},e.executeInstallPnpm=function(){(0,a.logInfoPrintConsole)(`Installing pnpm@${e.PNPM_VERSION}...`);const t=(0,s.getNpmPath)();!function(){const t=c.resolve(i.HVIGOR_WRAPPER_TOOLS_HOME,i.DEFAULT_PACKAGE_JSON);try{o.existsSync(i.HVIGOR_WRAPPER_TOOLS_HOME)||o.mkdirSync(i.HVIGOR_WRAPPER_TOOLS_HOME,{recursive:!0});const n={dependencies:{}};n.dependencies[i.PNPM]=e.PNPM_VERSION,o.writeFileSync(t,JSON.stringify(n))}catch(e){(0,a.logErrorAndExit)(`Error: EPERM: operation not permitted,create ${t} failed.`)}}(),(0,s.executeCommand)(t,["install","pnpm"],{cwd:i.HVIGOR_WRAPPER_TOOLS_HOME,stdio:["inherit","inherit","inherit"],env:process.env}),(0,a.logInfoPrintConsole)("Pnpm install success.")}}(O);var Y={},X={},Z={},Q={};Object.defineProperty(Q,"__esModule",{value:!0}),Q.Unicode=void 0;class ee{}Q.Unicode=ee,ee.Space_Separator=/[\u1680\u2000-\u200A\u202F\u205F\u3000]/,ee.ID_Start=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u09FC\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1C80-\u1C88\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDE80-\uDE9C\uDEA0-\uDED0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF75\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00\uDE10-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE4\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC03-\uDC37\uDC83-\uDCAF\uDCD0-\uDCE8\uDD03-\uDD26\uDD50-\uDD72\uDD76\uDD83-\uDDB2\uDDC1-\uDDC4\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE2B\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEDE\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3D\uDF50\uDF5D-\uDF61]|\uD805[\uDC00-\uDC34\uDC47-\uDC4A\uDC80-\uDCAF\uDCC4\uDCC5\uDCC7\uDD80-\uDDAE\uDDD8-\uDDDB\uDE00-\uDE2F\uDE44\uDE80-\uDEAA\uDF00-\uDF19]|\uD806[\uDCA0-\uDCDF\uDCFF\uDE00\uDE0B-\uDE32\uDE3A\uDE50\uDE5C-\uDE83\uDE86-\uDE89\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC2E\uDC40\uDC72-\uDC8F\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD30\uDD46]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDED0-\uDEED\uDF00-\uDF2F\uDF40-\uDF43\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50\uDF93-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB]|\uD83A[\uDC00-\uDCC4\uDD00-\uDD43]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]/,ee.ID_Continue=/[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u08D4-\u08E1\u08E3-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u09FC\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0AF9-\u0AFF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58-\u0C5A\u0C60-\u0C63\u0C66-\u0C6F\u0C80-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D00-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D54-\u0D57\u0D5F-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F5\u13F8-\u13FD\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1C80-\u1C88\u1CD0-\u1CD2\u1CD4-\u1CF9\u1D00-\u1DF9\u1DFB-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312E\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEA\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA7AE\uA7B0-\uA7B7\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C5\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA8FD\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB65\uAB70-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2F\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]|\uD800[\uDC00-\uDC0B\uDC0D-\uDC26\uDC28-\uDC3A\uDC3C\uDC3D\uDC3F-\uDC4D\uDC50-\uDC5D\uDC80-\uDCFA\uDD40-\uDD74\uDDFD\uDE80-\uDE9C\uDEA0-\uDED0\uDEE0\uDF00-\uDF1F\uDF2D-\uDF4A\uDF50-\uDF7A\uDF80-\uDF9D\uDFA0-\uDFC3\uDFC8-\uDFCF\uDFD1-\uDFD5]|\uD801[\uDC00-\uDC9D\uDCA0-\uDCA9\uDCB0-\uDCD3\uDCD8-\uDCFB\uDD00-\uDD27\uDD30-\uDD63\uDE00-\uDF36\uDF40-\uDF55\uDF60-\uDF67]|\uD802[\uDC00-\uDC05\uDC08\uDC0A-\uDC35\uDC37\uDC38\uDC3C\uDC3F-\uDC55\uDC60-\uDC76\uDC80-\uDC9E\uDCE0-\uDCF2\uDCF4\uDCF5\uDD00-\uDD15\uDD20-\uDD39\uDD80-\uDDB7\uDDBE\uDDBF\uDE00-\uDE03\uDE05\uDE06\uDE0C-\uDE13\uDE15-\uDE17\uDE19-\uDE33\uDE38-\uDE3A\uDE3F\uDE60-\uDE7C\uDE80-\uDE9C\uDEC0-\uDEC7\uDEC9-\uDEE6\uDF00-\uDF35\uDF40-\uDF55\uDF60-\uDF72\uDF80-\uDF91]|\uD803[\uDC00-\uDC48\uDC80-\uDCB2\uDCC0-\uDCF2]|\uD804[\uDC00-\uDC46\uDC66-\uDC6F\uDC7F-\uDCBA\uDCD0-\uDCE8\uDCF0-\uDCF9\uDD00-\uDD34\uDD36-\uDD3F\uDD50-\uDD73\uDD76\uDD80-\uDDC4\uDDCA-\uDDCC\uDDD0-\uDDDA\uDDDC\uDE00-\uDE11\uDE13-\uDE37\uDE3E\uDE80-\uDE86\uDE88\uDE8A-\uDE8D\uDE8F-\uDE9D\uDE9F-\uDEA8\uDEB0-\uDEEA\uDEF0-\uDEF9\uDF00-\uDF03\uDF05-\uDF0C\uDF0F\uDF10\uDF13-\uDF28\uDF2A-\uDF30\uDF32\uDF33\uDF35-\uDF39\uDF3C-\uDF44\uDF47\uDF48\uDF4B-\uDF4D\uDF50\uDF57\uDF5D-\uDF63\uDF66-\uDF6C\uDF70-\uDF74]|\uD805[\uDC00-\uDC4A\uDC50-\uDC59\uDC80-\uDCC5\uDCC7\uDCD0-\uDCD9\uDD80-\uDDB5\uDDB8-\uDDC0\uDDD8-\uDDDD\uDE00-\uDE40\uDE44\uDE50-\uDE59\uDE80-\uDEB7\uDEC0-\uDEC9\uDF00-\uDF19\uDF1D-\uDF2B\uDF30-\uDF39]|\uD806[\uDCA0-\uDCE9\uDCFF\uDE00-\uDE3E\uDE47\uDE50-\uDE83\uDE86-\uDE99\uDEC0-\uDEF8]|\uD807[\uDC00-\uDC08\uDC0A-\uDC36\uDC38-\uDC40\uDC50-\uDC59\uDC72-\uDC8F\uDC92-\uDCA7\uDCA9-\uDCB6\uDD00-\uDD06\uDD08\uDD09\uDD0B-\uDD36\uDD3A\uDD3C\uDD3D\uDD3F-\uDD47\uDD50-\uDD59]|\uD808[\uDC00-\uDF99]|\uD809[\uDC00-\uDC6E\uDC80-\uDD43]|[\uD80C\uD81C-\uD820\uD840-\uD868\uD86A-\uD86C\uD86F-\uD872\uD874-\uD879][\uDC00-\uDFFF]|\uD80D[\uDC00-\uDC2E]|\uD811[\uDC00-\uDE46]|\uD81A[\uDC00-\uDE38\uDE40-\uDE5E\uDE60-\uDE69\uDED0-\uDEED\uDEF0-\uDEF4\uDF00-\uDF36\uDF40-\uDF43\uDF50-\uDF59\uDF63-\uDF77\uDF7D-\uDF8F]|\uD81B[\uDF00-\uDF44\uDF50-\uDF7E\uDF8F-\uDF9F\uDFE0\uDFE1]|\uD821[\uDC00-\uDFEC]|\uD822[\uDC00-\uDEF2]|\uD82C[\uDC00-\uDD1E\uDD70-\uDEFB]|\uD82F[\uDC00-\uDC6A\uDC70-\uDC7C\uDC80-\uDC88\uDC90-\uDC99\uDC9D\uDC9E]|\uD834[\uDD65-\uDD69\uDD6D-\uDD72\uDD7B-\uDD82\uDD85-\uDD8B\uDDAA-\uDDAD\uDE42-\uDE44]|\uD835[\uDC00-\uDC54\uDC56-\uDC9C\uDC9E\uDC9F\uDCA2\uDCA5\uDCA6\uDCA9-\uDCAC\uDCAE-\uDCB9\uDCBB\uDCBD-\uDCC3\uDCC5-\uDD05\uDD07-\uDD0A\uDD0D-\uDD14\uDD16-\uDD1C\uDD1E-\uDD39\uDD3B-\uDD3E\uDD40-\uDD44\uDD46\uDD4A-\uDD50\uDD52-\uDEA5\uDEA8-\uDEC0\uDEC2-\uDEDA\uDEDC-\uDEFA\uDEFC-\uDF14\uDF16-\uDF34\uDF36-\uDF4E\uDF50-\uDF6E\uDF70-\uDF88\uDF8A-\uDFA8\uDFAA-\uDFC2\uDFC4-\uDFCB\uDFCE-\uDFFF]|\uD836[\uDE00-\uDE36\uDE3B-\uDE6C\uDE75\uDE84\uDE9B-\uDE9F\uDEA1-\uDEAF]|\uD838[\uDC00-\uDC06\uDC08-\uDC18\uDC1B-\uDC21\uDC23\uDC24\uDC26-\uDC2A]|\uD83A[\uDC00-\uDCC4\uDCD0-\uDCD6\uDD00-\uDD4A\uDD50-\uDD59]|\uD83B[\uDE00-\uDE03\uDE05-\uDE1F\uDE21\uDE22\uDE24\uDE27\uDE29-\uDE32\uDE34-\uDE37\uDE39\uDE3B\uDE42\uDE47\uDE49\uDE4B\uDE4D-\uDE4F\uDE51\uDE52\uDE54\uDE57\uDE59\uDE5B\uDE5D\uDE5F\uDE61\uDE62\uDE64\uDE67-\uDE6A\uDE6C-\uDE72\uDE74-\uDE77\uDE79-\uDE7C\uDE7E\uDE80-\uDE89\uDE8B-\uDE9B\uDEA1-\uDEA3\uDEA5-\uDEA9\uDEAB-\uDEBB]|\uD869[\uDC00-\uDED6\uDF00-\uDFFF]|\uD86D[\uDC00-\uDF34\uDF40-\uDFFF]|\uD86E[\uDC00-\uDC1D\uDC20-\uDFFF]|\uD873[\uDC00-\uDEA1\uDEB0-\uDFFF]|\uD87A[\uDC00-\uDFE0]|\uD87E[\uDC00-\uDE1D]|\uDB40[\uDD00-\uDDEF]/,Object.defineProperty(Z,"__esModule",{value:!0}),Z.JudgeUtil=void 0;const te=Q;Z.JudgeUtil=class{static isIgnoreChar(e){return"string"==typeof e&&("\t"===e||"\v"===e||"\f"===e||" "===e||" "===e||"\ufeff"===e||"\n"===e||"\r"===e||"\u2028"===e||"\u2029"===e)}static isSpaceSeparator(e){return"string"==typeof e&&te.Unicode.Space_Separator.test(e)}static isIdStartChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||"$"===e||"_"===e||te.Unicode.ID_Start.test(e))}static isIdContinueChar(e){return"string"==typeof e&&(e>="a"&&e<="z"||e>="A"&&e<="Z"||e>="0"&&e<="9"||"$"===e||"_"===e||"‌"===e||"‍"===e||te.Unicode.ID_Continue.test(e))}static isDigitWithoutZero(e){return/[1-9]/.test(e)}static isDigit(e){return"string"==typeof e&&/[0-9]/.test(e)}static isHexDigit(e){return"string"==typeof e&&/[0-9A-Fa-f]/.test(e)}};var ne={},re={fromCallback:function(e){return Object.defineProperty((function(...t){if("function"!=typeof t[t.length-1])return new Promise(((n,r)=>{e.call(this,...t,((e,t)=>null!=e?r(e):n(t)))}));e.apply(this,t)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(...t){const n=t[t.length-1];if("function"!=typeof n)return e.apply(this,t);e.apply(this,t.slice(0,-1)).then((e=>n(null,e)),n)}),"name",{value:e.name})}},ue=y.default,oe=process.cwd,ie=null,se=process.env.GRACEFUL_FS_PLATFORM||process.platform;process.cwd=function(){return ie||(ie=oe.call(process)),ie};try{process.cwd()}catch(e){}if("function"==typeof process.chdir){var ce=process.chdir;process.chdir=function(e){ie=null,ce.call(process,e)},Object.setPrototypeOf&&Object.setPrototypeOf(process.chdir,ce)}var ae=function(e){ue.hasOwnProperty("O_SYMLINK")&&process.version.match(/^v0\.6\.[0-2]|^v0\.5\./)&&function(e){e.lchmod=function(t,n,r){e.open(t,ue.O_WRONLY|ue.O_SYMLINK,n,(function(t,u){t?r&&r(t):e.fchmod(u,n,(function(t){e.close(u,(function(e){r&&r(t||e)}))}))}))},e.lchmodSync=function(t,n){var r,u=e.openSync(t,ue.O_WRONLY|ue.O_SYMLINK,n),o=!0;try{r=e.fchmodSync(u,n),o=!1}finally{if(o)try{e.closeSync(u)}catch(e){}else e.closeSync(u)}return r}}(e);e.lutimes||function(e){ue.hasOwnProperty("O_SYMLINK")&&e.futimes?(e.lutimes=function(t,n,r,u){e.open(t,ue.O_SYMLINK,(function(t,o){t?u&&u(t):e.futimes(o,n,r,(function(t){e.close(o,(function(e){u&&u(t||e)}))}))}))},e.lutimesSync=function(t,n,r){var u,o=e.openSync(t,ue.O_SYMLINK),i=!0;try{u=e.futimesSync(o,n,r),i=!1}finally{if(i)try{e.closeSync(o)}catch(e){}else e.closeSync(o)}return u}):e.futimes&&(e.lutimes=function(e,t,n,r){r&&process.nextTick(r)},e.lutimesSync=function(){})}(e);e.chown=r(e.chown),e.fchown=r(e.fchown),e.lchown=r(e.lchown),e.chmod=t(e.chmod),e.fchmod=t(e.fchmod),e.lchmod=t(e.lchmod),e.chownSync=u(e.chownSync),e.fchownSync=u(e.fchownSync),e.lchownSync=u(e.lchownSync),e.chmodSync=n(e.chmodSync),e.fchmodSync=n(e.fchmodSync),e.lchmodSync=n(e.lchmodSync),e.stat=o(e.stat),e.fstat=o(e.fstat),e.lstat=o(e.lstat),e.statSync=i(e.statSync),e.fstatSync=i(e.fstatSync),e.lstatSync=i(e.lstatSync),e.chmod&&!e.lchmod&&(e.lchmod=function(e,t,n){n&&process.nextTick(n)},e.lchmodSync=function(){});e.chown&&!e.lchown&&(e.lchown=function(e,t,n,r){r&&process.nextTick(r)},e.lchownSync=function(){});"win32"===se&&(e.rename="function"!=typeof e.rename?e.rename:function(t){function n(n,r,u){var o=Date.now(),i=0;t(n,r,(function s(c){if(c&&("EACCES"===c.code||"EPERM"===c.code||"EBUSY"===c.code)&&Date.now()-o<6e4)return setTimeout((function(){e.stat(r,(function(e,o){e&&"ENOENT"===e.code?t(n,r,s):u(c)}))}),i),void(i<100&&(i+=10));u&&u(c)}))}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.rename));function t(t){return t?function(n,r,u){return t.call(e,n,r,(function(e){s(e)&&(e=null),u&&u.apply(this,arguments)}))}:t}function n(t){return t?function(n,r){try{return t.call(e,n,r)}catch(e){if(!s(e))throw e}}:t}function r(t){return t?function(n,r,u,o){return t.call(e,n,r,u,(function(e){s(e)&&(e=null),o&&o.apply(this,arguments)}))}:t}function u(t){return t?function(n,r,u){try{return t.call(e,n,r,u)}catch(e){if(!s(e))throw e}}:t}function o(t){return t?function(n,r,u){function o(e,t){t&&(t.uid<0&&(t.uid+=4294967296),t.gid<0&&(t.gid+=4294967296)),u&&u.apply(this,arguments)}return"function"==typeof r&&(u=r,r=null),r?t.call(e,n,r,o):t.call(e,n,o)}:t}function i(t){return t?function(n,r){var u=r?t.call(e,n,r):t.call(e,n);return u&&(u.uid<0&&(u.uid+=4294967296),u.gid<0&&(u.gid+=4294967296)),u}:t}function s(e){return!e||("ENOSYS"===e.code||!(process.getuid&&0===process.getuid()||"EINVAL"!==e.code&&"EPERM"!==e.code))}e.read="function"!=typeof e.read?e.read:function(t){function n(n,r,u,o,i,s){var c;if(s&&"function"==typeof s){var a=0;c=function(l,f,d){if(l&&"EAGAIN"===l.code&&a<10)return a++,t.call(e,n,r,u,o,i,c);s.apply(this,arguments)}}return t.call(e,n,r,u,o,i,c)}return Object.setPrototypeOf&&Object.setPrototypeOf(n,t),n}(e.read),e.readSync="function"!=typeof e.readSync?e.readSync:(c=e.readSync,function(t,n,r,u,o){for(var i=0;;)try{return c.call(e,t,n,r,u,o)}catch(e){if("EAGAIN"===e.code&&i<10){i++;continue}throw e}});var c};var le=C.default.Stream,fe=function(e){return{ReadStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this);var u=this;this.path=n,this.fd=null,this.readable=!0,this.paused=!1,this.flags="r",this.mode=438,this.bufferSize=65536,r=r||{};for(var o=Object.keys(r),i=0,s=o.length;ithis.end)throw new Error("start must be <= end");this.pos=this.start}if(null!==this.fd)return void process.nextTick((function(){u._read()}));e.open(this.path,this.flags,this.mode,(function(e,t){if(e)return u.emit("error",e),void(u.readable=!1);u.fd=t,u.emit("open",t),u._read()}))},WriteStream:function t(n,r){if(!(this instanceof t))return new t(n,r);le.call(this),this.path=n,this.fd=null,this.writable=!0,this.flags="w",this.encoding="binary",this.mode=438,this.bytesWritten=0,r=r||{};for(var u=Object.keys(r),o=0,i=u.length;o= zero");this.pos=this.start}this.busy=!1,this._queue=[],null===this.fd&&(this._open=e.open,this._queue.push([this._open,this.path,this.flags,this.mode,void 0]),this.flush())}}};var de=function(e){if(null===e||"object"!=typeof e)return e;if(e instanceof Object)var t={__proto__:De(e)};else t=Object.create(null);return Object.getOwnPropertyNames(e).forEach((function(n){Object.defineProperty(t,n,Object.getOwnPropertyDescriptor(e,n))})),t},De=Object.getPrototypeOf||function(e){return e.__proto__};var pe,Ee,me=D.default,he=ae,ye=fe,Ce=de,Fe=F.default;function ge(e,t){Object.defineProperty(e,pe,{get:function(){return t}})}"function"==typeof Symbol&&"function"==typeof Symbol.for?(pe=Symbol.for("graceful-fs.queue"),Ee=Symbol.for("graceful-fs.previous")):(pe="___graceful-fs.queue",Ee="___graceful-fs.previous");var Ae=function(){};if(Fe.debuglog?Ae=Fe.debuglog("gfs4"):/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&(Ae=function(){var e=Fe.format.apply(Fe,arguments);e="GFS4: "+e.split(/\n/).join("\nGFS4: "),console.error(e)}),!me[pe]){var ve=w[pe]||[];ge(me,ve),me.close=function(e){function t(t,n){return e.call(me,t,(function(e){e||_e(),"function"==typeof n&&n.apply(this,arguments)}))}return Object.defineProperty(t,Ee,{value:e}),t}(me.close),me.closeSync=function(e){function t(t){e.apply(me,arguments),_e()}return Object.defineProperty(t,Ee,{value:e}),t}(me.closeSync),/\bgfs4\b/i.test(process.env.NODE_DEBUG||"")&&process.on("exit",(function(){Ae(me[pe]),g.default.equal(me[pe].length,0)}))}w[pe]||ge(w,me[pe]);var Se,we=Oe(Ce(me));function Oe(e){he(e),e.gracefulify=Oe,e.createReadStream=function(t,n){return new e.ReadStream(t,n)},e.createWriteStream=function(t,n){return new e.WriteStream(t,n)};var t=e.readFile;e.readFile=function(e,n,r){"function"==typeof n&&(r=n,n=null);return function e(n,r,u,o){return t(n,r,(function(t){!t||"EMFILE"!==t.code&&"ENFILE"!==t.code?"function"==typeof u&&u.apply(this,arguments):be([e,[n,r,u],t,o||Date.now(),Date.now()])}))}(e,n,r)};var n=e.writeFile;e.writeFile=function(e,t,r,u){"function"==typeof r&&(u=r,r=null);return function e(t,r,u,o,i){return n(t,r,u,(function(n){!n||"EMFILE"!==n.code&&"ENFILE"!==n.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,r,u,o],n,i||Date.now(),Date.now()])}))}(e,t,r,u)};var r=e.appendFile;r&&(e.appendFile=function(e,t,n,u){"function"==typeof n&&(u=n,n=null);return function e(t,n,u,o,i){return r(t,n,u,(function(r){!r||"EMFILE"!==r.code&&"ENFILE"!==r.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,u,o],r,i||Date.now(),Date.now()])}))}(e,t,n,u)});var u=e.copyFile;u&&(e.copyFile=function(e,t,n,r){"function"==typeof n&&(r=n,n=0);return function e(t,n,r,o,i){return u(t,n,r,(function(u){!u||"EMFILE"!==u.code&&"ENFILE"!==u.code?"function"==typeof o&&o.apply(this,arguments):be([e,[t,n,r,o],u,i||Date.now(),Date.now()])}))}(e,t,n,r)});var o=e.readdir;e.readdir=function(e,t,n){"function"==typeof t&&(n=t,t=null);var r=i.test(process.version)?function(e,t,n,r){return o(e,u(e,t,n,r))}:function(e,t,n,r){return o(e,t,u(e,t,n,r))};return r(e,t,n);function u(e,t,n,u){return function(o,i){!o||"EMFILE"!==o.code&&"ENFILE"!==o.code?(i&&i.sort&&i.sort(),"function"==typeof n&&n.call(this,o,i)):be([r,[e,t,n],o,u||Date.now(),Date.now()])}}};var i=/^v[0-5]\./;if("v0.8"===process.version.substr(0,4)){var s=ye(e);d=s.ReadStream,D=s.WriteStream}var c=e.ReadStream;c&&(d.prototype=Object.create(c.prototype),d.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.autoClose&&e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n),e.read())}))});var a=e.WriteStream;a&&(D.prototype=Object.create(a.prototype),D.prototype.open=function(){var e=this;E(e.path,e.flags,e.mode,(function(t,n){t?(e.destroy(),e.emit("error",t)):(e.fd=n,e.emit("open",n))}))}),Object.defineProperty(e,"ReadStream",{get:function(){return d},set:function(e){d=e},enumerable:!0,configurable:!0}),Object.defineProperty(e,"WriteStream",{get:function(){return D},set:function(e){D=e},enumerable:!0,configurable:!0});var l=d;Object.defineProperty(e,"FileReadStream",{get:function(){return l},set:function(e){l=e},enumerable:!0,configurable:!0});var f=D;function d(e,t){return this instanceof d?(c.apply(this,arguments),this):d.apply(Object.create(d.prototype),arguments)}function D(e,t){return this instanceof D?(a.apply(this,arguments),this):D.apply(Object.create(D.prototype),arguments)}Object.defineProperty(e,"FileWriteStream",{get:function(){return f},set:function(e){f=e},enumerable:!0,configurable:!0});var p=e.open;function E(e,t,n,r){return"function"==typeof n&&(r=n,n=null),function e(t,n,r,u,o){return p(t,n,r,(function(i,s){!i||"EMFILE"!==i.code&&"ENFILE"!==i.code?"function"==typeof u&&u.apply(this,arguments):be([e,[t,n,r,u],i,o||Date.now(),Date.now()])}))}(e,t,n,r)}return e.open=E,e}function be(e){Ae("ENQUEUE",e[0].name,e[1]),me[pe].push(e),Be()}function _e(){for(var e=Date.now(),t=0;t2&&(me[pe][t][3]=e,me[pe][t][4]=e);Be()}function Be(){if(clearTimeout(Se),Se=void 0,0!==me[pe].length){var e=me[pe].shift(),t=e[0],n=e[1],r=e[2],u=e[3],o=e[4];if(void 0===u)Ae("RETRY",t.name,n),t.apply(null,n);else if(Date.now()-u>=6e4){Ae("TIMEOUT",t.name,n);var i=n.pop();"function"==typeof i&&i.call(null,r)}else{var s=Date.now()-o,c=Math.max(o-u,1);s>=Math.min(1.2*c,100)?(Ae("RETRY",t.name,n),t.apply(null,n.concat([u]))):me[pe].push(e)}void 0===Se&&(Se=setTimeout(Be,0))}}process.env.TEST_GRACEFUL_FS_GLOBAL_PATCH&&!me.__patched&&(we=Oe(me),me.__patched=!0),function(e){const t=re.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchmod","lchown","link","lstat","mkdir","mkdtemp","open","opendir","readdir","readFile","readlink","realpath","rename","rm","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.assign(e,n),r.forEach((r=>{e[r]=t(n[r])})),e.realpath.native=t(n.realpath.native),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.writev&&(e.writev=function(e,t,...r){return"function"==typeof r[r.length-1]?n.writev(e,t,...r):new Promise(((u,o)=>{n.writev(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffers:n})}))}))})}(ne);var Pe={},ke={};const xe=p.default;ke.checkPath=function(e){if("win32"===process.platform){if(/[<>:"|?*]/.test(e.replace(xe.parse(e).root,""))){const t=new Error(`Path contains invalid characters: ${e}`);throw t.code="EINVAL",t}}};const Ne=ne,{checkPath:Ie}=ke,Te=e=>"number"==typeof e?e:{mode:511,...e}.mode;Pe.makeDir=async(e,t)=>(Ie(e),Ne.mkdir(e,{mode:Te(t),recursive:!0})),Pe.makeDirSync=(e,t)=>(Ie(e),Ne.mkdirSync(e,{mode:Te(t),recursive:!0}));const Re=re.fromPromise,{makeDir:Me,makeDirSync:Le}=Pe,je=Re(Me);var $e={mkdirs:je,mkdirsSync:Le,mkdirp:je,mkdirpSync:Le,ensureDir:je,ensureDirSync:Le};const He=re.fromPromise,Je=ne;var Ge={pathExists:He((function(e){return Je.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:Je.existsSync};const Ve=we;var Ue=function(e,t,n,r){Ve.open(e,"r+",((e,u)=>{if(e)return r(e);Ve.futimes(u,t,n,(e=>{Ve.close(u,(t=>{r&&r(e||t)}))}))}))},We=function(e,t,n){const r=Ve.openSync(e,"r+");return Ve.futimesSync(r,t,n),Ve.closeSync(r)};const ze=ne,Ke=p.default,qe=F.default;function Ye(e,t,n){const r=n.dereference?e=>ze.stat(e,{bigint:!0}):e=>ze.lstat(e,{bigint:!0});return Promise.all([r(e),r(t).catch((e=>{if("ENOENT"===e.code)return null;throw e}))]).then((([e,t])=>({srcStat:e,destStat:t})))}function Xe(e,t){return t.ino&&t.dev&&t.ino===e.ino&&t.dev===e.dev}function Ze(e,t){const n=Ke.resolve(e).split(Ke.sep).filter((e=>e)),r=Ke.resolve(t).split(Ke.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function Qe(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var et={checkPaths:function(e,t,n,r,u){qe.callbackify(Ye)(e,t,r,((r,o)=>{if(r)return u(r);const{srcStat:i,destStat:s}=o;if(s){if(Xe(i,s)){const r=Ke.basename(e),o=Ke.basename(t);return"move"===n&&r!==o&&r.toLowerCase()===o.toLowerCase()?u(null,{srcStat:i,destStat:s,isChangingCase:!0}):u(new Error("Source and destination must not be the same."))}if(i.isDirectory()&&!s.isDirectory())return u(new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`));if(!i.isDirectory()&&s.isDirectory())return u(new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`))}return i.isDirectory()&&Ze(e,t)?u(new Error(Qe(e,t,n))):u(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n,r){const{srcStat:u,destStat:o}=function(e,t,n){let r;const u=n.dereference?e=>ze.statSync(e,{bigint:!0}):e=>ze.lstatSync(e,{bigint:!0}),o=u(e);try{r=u(t)}catch(e){if("ENOENT"===e.code)return{srcStat:o,destStat:null};throw e}return{srcStat:o,destStat:r}}(e,t,r);if(o){if(Xe(u,o)){const r=Ke.basename(e),i=Ke.basename(t);if("move"===n&&r!==i&&r.toLowerCase()===i.toLowerCase())return{srcStat:u,destStat:o,isChangingCase:!0};throw new Error("Source and destination must not be the same.")}if(u.isDirectory()&&!o.isDirectory())throw new Error(`Cannot overwrite non-directory '${t}' with directory '${e}'.`);if(!u.isDirectory()&&o.isDirectory())throw new Error(`Cannot overwrite directory '${t}' with non-directory '${e}'.`)}if(u.isDirectory()&&Ze(e,t))throw new Error(Qe(e,t,n));return{srcStat:u,destStat:o}},checkParentPaths:function e(t,n,r,u,o){const i=Ke.resolve(Ke.dirname(t)),s=Ke.resolve(Ke.dirname(r));if(s===i||s===Ke.parse(s).root)return o();ze.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):Xe(n,c)?o(new Error(Qe(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=Ke.resolve(Ke.dirname(t)),i=Ke.resolve(Ke.dirname(r));if(i===o||i===Ke.parse(i).root)return;let s;try{s=ze.statSync(i,{bigint:!0})}catch(e){if("ENOENT"===e.code)return;throw e}if(Xe(n,s))throw new Error(Qe(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ze,areIdentical:Xe};const tt=we,nt=p.default,rt=$e.mkdirs,ut=Ge.pathExists,ot=Ue,it=et;function st(e,t,n,r,u){const o=nt.dirname(n);ut(o,((i,s)=>i?u(i):s?at(e,t,n,r,u):void rt(o,(o=>o?u(o):at(e,t,n,r,u)))))}function ct(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function at(e,t,n,r,u){(r.dereference?tt.stat:tt.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){return t?Dt(n,r,u,o):function(e,t,n,r,u){tt.mkdir(n,(o=>{if(o)return u(o);Dt(t,n,r,(t=>t?u(t):dt(n,e,u)))}))}(e.mode,n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();tt.unlink(n,(o=>o?u(o):lt(e,t,n,r,u)))}(e,n,r,u,o):lt(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){tt.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=nt.resolve(process.cwd(),o)),e?void tt.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?tt.symlink(o,n,u):u(t):(r.dereference&&(i=nt.resolve(process.cwd(),i)),it.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&it.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){tt.unlink(t,(r=>r?n(r):tt.symlink(e,t,n)))}(o,n,u)))):tt.symlink(o,n,u))))}(e,t,n,r,u):i.isSocket()?u(new Error(`Cannot copy a socket file: ${t}`)):i.isFIFO()?u(new Error(`Cannot copy a FIFO pipe: ${t}`)):u(new Error(`Unknown file: ${t}`))))}function lt(e,t,n,r,u){tt.copyFile(t,n,(o=>o?u(o):r.preserveTimestamps?function(e,t,n,r){if(function(e){return 0==(128&e)}(e))return function(e,t,n){return dt(e,128|t,n)}(n,e,(u=>u?r(u):ft(e,t,n,r)));return ft(e,t,n,r)}(e.mode,t,n,u):dt(n,e.mode,u)))}function ft(e,t,n,r){!function(e,t,n){tt.stat(e,((e,r)=>e?n(e):ot(t,r.atime,r.mtime,n)))}(t,n,(t=>t?r(t):dt(n,e,r)))}function dt(e,t,n){return tt.chmod(e,t,n)}function Dt(e,t,n,r){tt.readdir(e,((u,o)=>u?r(u):pt(o,e,t,n,r)))}function pt(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=nt.join(n,t),s=nt.join(r,t);it.checkPaths(i,s,"copy",u,((t,c)=>{if(t)return o(t);const{destStat:a}=c;!function(e,t,n,r,u){r.filter?ct(at,e,t,n,r,u):at(e,t,n,r,u)}(a,i,s,u,(t=>t?o(t):pt(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Et=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),it.checkPaths(e,t,"copy",n,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;it.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?ct(st,s,e,t,n,r):st(s,e,t,n,r)))}))};const mt=we,ht=p.default,yt=$e.mkdirsSync,Ct=We,Ft=et;function gt(e,t,n,r){const u=(r.dereference?mt.statSync:mt.lstatSync)(t);if(u.isDirectory())return function(e,t,n,r,u){return t?St(n,r,u):function(e,t,n,r){return mt.mkdirSync(n),St(t,n,r),vt(n,e)}(e.mode,n,r,u)}(u,e,t,n,r);if(u.isFile()||u.isCharacterDevice()||u.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return mt.unlinkSync(n),At(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):At(e,n,r,u)}(u,e,t,n,r);if(u.isSymbolicLink())return function(e,t,n,r){let u=mt.readlinkSync(t);r.dereference&&(u=ht.resolve(process.cwd(),u));if(e){let e;try{e=mt.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return mt.symlinkSync(u,n);throw e}if(r.dereference&&(e=ht.resolve(process.cwd(),e)),Ft.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(mt.statSync(n).isDirectory()&&Ft.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return mt.unlinkSync(t),mt.symlinkSync(e,t)}(u,n)}return mt.symlinkSync(u,n)}(e,t,n,r);if(u.isSocket())throw new Error(`Cannot copy a socket file: ${t}`);if(u.isFIFO())throw new Error(`Cannot copy a FIFO pipe: ${t}`);throw new Error(`Unknown file: ${t}`)}function At(e,t,n,r){return mt.copyFileSync(t,n),r.preserveTimestamps&&function(e,t,n){(function(e){return 0==(128&e)})(e)&&function(e,t){vt(e,128|t)}(n,e);(function(e,t){const n=mt.statSync(e);Ct(t,n.atime,n.mtime)})(t,n)}(e.mode,t,n),vt(n,e.mode)}function vt(e,t){return mt.chmodSync(e,t)}function St(e,t,n){mt.readdirSync(e).forEach((r=>function(e,t,n,r){const u=ht.join(t,e),o=ht.join(n,e),{destStat:i}=Ft.checkPathsSync(u,o,"copy",r);return function(e,t,n,r){if(!r.filter||r.filter(t,n))return gt(e,t,n,r)}(i,u,o,r)}(r,e,t,n)))}var wt=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=Ft.checkPathsSync(e,t,"copy",n);return Ft.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ht.dirname(n);mt.existsSync(u)||yt(u);return gt(e,t,n,r)}(u,e,t,n)};var Ot={copy:(0,re.fromCallback)(Et),copySync:wt};const bt=we,_t=p.default,Bt=g.default,Pt="win32"===process.platform;function kt(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||bt[t],e[t+="Sync"]=e[t]||bt[t]})),e.maxBusyTries=e.maxBusyTries||3}function xt(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt.strictEqual(typeof n,"function","rimraf: callback function required"),Bt(t,"rimraf: invalid options argument provided"),Bt.strictEqual(typeof t,"object","rimraf: options should be object"),kt(t),Nt(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rNt(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Nt(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&Pt?It(e,t,r,n):u&&u.isDirectory()?Rt(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return Pt?It(e,t,r,n):Rt(e,t,r,n);if("EISDIR"===r.code)return Rt(e,t,r,n)}return n(r)}))))}function It(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Rt(e,t,n,r):t.unlink(e,r)}))}))}function Tt(e,t,n){let r;Bt(e),Bt(t);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?Lt(e,t,n):t.unlinkSync(e)}function Rt(e,t,n,r){Bt(e),Bt(t),Bt("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Bt(e),Bt(t),Bt("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{xt(_t.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Mt(e,t){let n;kt(t=t||{}),Bt(e,"rimraf: missing path"),Bt.strictEqual(typeof e,"string","rimraf: path should be a string"),Bt(t,"rimraf: missing options"),Bt.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&Pt&&Tt(e,t,n)}try{n&&n.isDirectory()?Lt(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return Pt?Tt(e,t,n):Lt(e,t,n);if("EISDIR"!==n.code)throw n;Lt(e,t,n)}}function Lt(e,t,n){Bt(e),Bt(t);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Bt(e),Bt(t),t.readdirSync(e).forEach((n=>Mt(_t.join(e,n),t))),!Pt){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch{}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var jt=xt;xt.sync=Mt;const $t=we,Ht=re.fromCallback,Jt=jt;var Gt={remove:Ht((function(e,t){if($t.rm)return $t.rm(e,{recursive:!0,force:!0},t);Jt(e,t)})),removeSync:function(e){if($t.rmSync)return $t.rmSync(e,{recursive:!0,force:!0});Jt.sync(e)}};const Vt=re.fromPromise,Ut=ne,Wt=p.default,zt=$e,Kt=Gt,qt=Vt((async function(e){let t;try{t=await Ut.readdir(e)}catch{return zt.mkdirs(e)}return Promise.all(t.map((t=>Kt.remove(Wt.join(e,t)))))}));function Yt(e){let t;try{t=Ut.readdirSync(e)}catch{return zt.mkdirsSync(e)}t.forEach((t=>{t=Wt.join(e,t),Kt.removeSync(t)}))}var Xt={emptyDirSync:Yt,emptydirSync:Yt,emptyDir:qt,emptydir:qt};const Zt=re.fromCallback,Qt=p.default,en=we,tn=$e;var nn={createFile:Zt((function(e,t){function n(){en.writeFile(e,"",(e=>{if(e)return t(e);t()}))}en.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Qt.dirname(e);en.stat(o,((e,r)=>{if(e)return"ENOENT"===e.code?tn.mkdirs(o,(e=>{if(e)return t(e);n()})):t(e);r.isDirectory()?n():en.readdir(o,(e=>{if(e)return t(e)}))}))}))})),createFileSync:function(e){let t;try{t=en.statSync(e)}catch{}if(t&&t.isFile())return;const n=Qt.dirname(e);try{en.statSync(n).isDirectory()||en.readdirSync(n)}catch(e){if(!e||"ENOENT"!==e.code)throw e;tn.mkdirsSync(n)}en.writeFileSync(e,"")}};const rn=re.fromCallback,un=p.default,on=we,sn=$e,cn=Ge.pathExists,{areIdentical:an}=et;var ln={createLink:rn((function(e,t,n){function r(e,t){on.link(e,t,(e=>{if(e)return n(e);n(null)}))}on.lstat(t,((u,o)=>{on.lstat(e,((u,i)=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);if(o&&an(i,o))return n(null);const s=un.dirname(t);cn(s,((u,o)=>u?n(u):o?r(e,t):void sn.mkdirs(s,(u=>{if(u)return n(u);r(e,t)}))))}))}))})),createLinkSync:function(e,t){let n;try{n=on.lstatSync(t)}catch{}try{const t=on.lstatSync(e);if(n&&an(t,n))return}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const r=un.dirname(t);return on.existsSync(r)||sn.mkdirsSync(r),on.linkSync(e,t)}};const fn=p.default,dn=we,Dn=Ge.pathExists;var pn={symlinkPaths:function(e,t,n){if(fn.isAbsolute(e))return dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=fn.dirname(t),u=fn.join(r,e);return Dn(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):dn.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:fn.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(fn.isAbsolute(e)){if(n=dn.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=fn.dirname(t),u=fn.join(r,e);if(n=dn.existsSync(u),n)return{toCwd:u,toDst:e};if(n=dn.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:fn.relative(r,e)}}}};const En=we;var mn={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);En.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=En.lstatSync(e)}catch{return"file"}return n&&n.isDirectory()?"dir":"file"}};const hn=re.fromCallback,yn=p.default,Cn=ne,Fn=$e.mkdirs,gn=$e.mkdirsSync,An=pn.symlinkPaths,vn=pn.symlinkPathsSync,Sn=mn.symlinkType,wn=mn.symlinkTypeSync,On=Ge.pathExists,{areIdentical:bn}=et;function _n(e,t,n,r){An(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,Sn(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=yn.dirname(t);On(o,((n,i)=>n?r(n):i?Cn.symlink(e,t,u,r):void Fn(o,(n=>{if(n)return r(n);Cn.symlink(e,t,u,r)}))))}))}))}var Bn={createSymlink:hn((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Cn.lstat(t,((u,o)=>{!u&&o.isSymbolicLink()?Promise.all([Cn.stat(e),Cn.stat(t)]).then((([u,o])=>{if(bn(u,o))return r(null);_n(e,t,n,r)})):_n(e,t,n,r)}))})),createSymlinkSync:function(e,t,n){let r;try{r=Cn.lstatSync(t)}catch{}if(r&&r.isSymbolicLink()){const n=Cn.statSync(e),r=Cn.statSync(t);if(bn(n,r))return}const u=vn(e,t);e=u.toDst,n=wn(u.toCwd,n);const o=yn.dirname(t);return Cn.existsSync(o)||gn(o),Cn.symlinkSync(e,t,n)}};const{createFile:Pn,createFileSync:kn}=nn,{createLink:xn,createLinkSync:Nn}=ln,{createSymlink:In,createSymlinkSync:Tn}=Bn;var Rn={createFile:Pn,createFileSync:kn,ensureFile:Pn,ensureFileSync:kn,createLink:xn,createLinkSync:Nn,ensureLink:xn,ensureLinkSync:Nn,createSymlink:In,createSymlinkSync:Tn,ensureSymlink:In,ensureSymlinkSync:Tn};var Mn={stringify:function(e,{EOL:t="\n",finalEOL:n=!0,replacer:r=null,spaces:u}={}){const o=n?t:"";return JSON.stringify(e,r,u).replace(/\n/g,t)+o},stripBom:function(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e.replace(/^\uFEFF/,"")}};let Ln;try{Ln=we}catch(e){Ln=D.default}const jn=re,{stringify:$n,stripBom:Hn}=Mn;const Jn=jn.fromPromise((async function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;let u,o=await jn.fromCallback(n.readFile)(e,t);o=Hn(o);try{u=JSON.parse(o,t?t.reviver:null)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}return u}));const Gn=jn.fromPromise((async function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);await jn.fromCallback(r.writeFile)(e,u,n)}));const Vn={readFile:Jn,readFileSync:function(e,t={}){"string"==typeof t&&(t={encoding:t});const n=t.fs||Ln,r=!("throws"in t)||t.throws;try{let r=n.readFileSync(e,t);return r=Hn(r),JSON.parse(r,t.reviver)}catch(t){if(r)throw t.message=`${e}: ${t.message}`,t;return null}},writeFile:Gn,writeFileSync:function(e,t,n={}){const r=n.fs||Ln,u=$n(t,n);return r.writeFileSync(e,u,n)}};var Un={readJson:Vn.readFile,readJsonSync:Vn.readFileSync,writeJson:Vn.writeFile,writeJsonSync:Vn.writeFileSync};const Wn=re.fromCallback,zn=we,Kn=p.default,qn=$e,Yn=Ge.pathExists;var Xn={outputFile:Wn((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Kn.dirname(e);Yn(u,((o,i)=>o?r(o):i?zn.writeFile(e,t,n,r):void qn.mkdirs(u,(u=>{if(u)return r(u);zn.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Kn.dirname(e);if(zn.existsSync(n))return zn.writeFileSync(e,...t);qn.mkdirsSync(n),zn.writeFileSync(e,...t)}};const{stringify:Zn}=Mn,{outputFile:Qn}=Xn;var er=async function(e,t,n={}){const r=Zn(t,n);await Qn(e,r,n)};const{stringify:tr}=Mn,{outputFileSync:nr}=Xn;var rr=function(e,t,n){const r=tr(t,n);nr(e,r,n)};const ur=re.fromPromise,or=Un;or.outputJson=ur(er),or.outputJsonSync=rr,or.outputJSON=or.outputJson,or.outputJSONSync=or.outputJsonSync,or.writeJSON=or.writeJson,or.writeJSONSync=or.writeJsonSync,or.readJSON=or.readJson,or.readJSONSync=or.readJsonSync;var ir=or;const sr=we,cr=p.default,ar=Ot.copy,lr=Gt.remove,fr=$e.mkdirp,dr=Ge.pathExists,Dr=et;function pr(e,t,n,r,u){return r?Er(e,t,n,u):n?lr(t,(r=>r?u(r):Er(e,t,n,u))):void dr(t,((r,o)=>r?u(r):o?u(new Error("dest already exists.")):Er(e,t,n,u)))}function Er(e,t,n,r){sr.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};ar(e,t,u,(t=>t?r(t):lr(e,r)))}(e,t,n,r):r()))}var mr=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;Dr.checkPaths(e,t,"move",n,((n,o)=>{if(n)return r(n);const{srcStat:i,isChangingCase:s=!1}=o;Dr.checkParentPaths(e,i,t,"move",(n=>n?r(n):function(e){const t=cr.dirname(e);return cr.parse(t).root===t}(t)?pr(e,t,u,s,r):void fr(cr.dirname(t),(n=>n?r(n):pr(e,t,u,s,r)))))}))};const hr=we,yr=p.default,Cr=Ot.copySync,Fr=Gt.removeSync,gr=$e.mkdirpSync,Ar=et;function vr(e,t,n){try{hr.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Cr(e,t,r),Fr(e)}(e,t,n)}}var Sr=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u,isChangingCase:o=!1}=Ar.checkPathsSync(e,t,"move",n);return Ar.checkParentPathsSync(e,u,t,"move"),function(e){const t=yr.dirname(e);return yr.parse(t).root===t}(t)||gr(yr.dirname(t)),function(e,t,n,r){if(r)return vr(e,t,n);if(n)return Fr(t),vr(e,t,n);if(hr.existsSync(t))throw new Error("dest already exists.");return vr(e,t,n)}(e,t,r,o)};var wr,Or,br,_r,Br,Pr={move:(0,re.fromCallback)(mr),moveSync:Sr},kr={...ne,...Ot,...Xt,...Rn,...ir,...$e,...Pr,...Xn,...Ge,...Gt},xr={},Nr={exports:{}},Ir={exports:{}};function Tr(){if(Or)return wr;Or=1;var e=1e3,t=60*e,n=60*t,r=24*n,u=7*r,o=365.25*r;function i(e,t,n,r){var u=t>=1.5*n;return Math.round(e/n)+" "+r+(u?"s":"")}return wr=function(s,c){c=c||{};var a=typeof s;if("string"===a&&s.length>0)return function(i){if((i=String(i)).length>100)return;var s=/^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(i);if(!s)return;var c=parseFloat(s[1]);switch((s[2]||"ms").toLowerCase()){case"years":case"year":case"yrs":case"yr":case"y":return c*o;case"weeks":case"week":case"w":return c*u;case"days":case"day":case"d":return c*r;case"hours":case"hour":case"hrs":case"hr":case"h":return c*n;case"minutes":case"minute":case"mins":case"min":case"m":return c*t;case"seconds":case"second":case"secs":case"sec":case"s":return c*e;case"milliseconds":case"millisecond":case"msecs":case"msec":case"ms":return c;default:return}}(s);if("number"===a&&isFinite(s))return c.long?function(u){var o=Math.abs(u);if(o>=r)return i(u,o,r,"day");if(o>=n)return i(u,o,n,"hour");if(o>=t)return i(u,o,t,"minute");if(o>=e)return i(u,o,e,"second");return u+" ms"}(s):function(u){var o=Math.abs(u);if(o>=r)return Math.round(u/r)+"d";if(o>=n)return Math.round(u/n)+"h";if(o>=t)return Math.round(u/t)+"m";if(o>=e)return Math.round(u/e)+"s";return u+"ms"}(s);throw new Error("val is not a non-empty string or a valid number. val="+JSON.stringify(s))}}function Rr(){if(_r)return br;return _r=1,br=function(e){function t(e){let r,u,o,i=null;function s(...e){if(!s.enabled)return;const n=s,u=Number(new Date),o=u-(r||u);n.diff=o,n.prev=r,n.curr=u,r=u,e[0]=t.coerce(e[0]),"string"!=typeof e[0]&&e.unshift("%O");let i=0;e[0]=e[0].replace(/%([a-zA-Z%])/g,((r,u)=>{if("%%"===r)return"%";i++;const o=t.formatters[u];if("function"==typeof o){const t=e[i];r=o.call(n,t),e.splice(i,1),i--}return r})),t.formatArgs.call(n,e);(n.log||t.log).apply(n,e)}return s.namespace=e,s.useColors=t.useColors(),s.color=t.selectColor(e),s.extend=n,s.destroy=t.destroy,Object.defineProperty(s,"enabled",{enumerable:!0,configurable:!1,get:()=>null!==i?i:(u!==t.namespaces&&(u=t.namespaces,o=t.enabled(e)),o),set:e=>{i=e}}),"function"==typeof t.init&&t.init(s),s}function n(e,n){const r=t(this.namespace+(void 0===n?":":n)+e);return r.log=this.log,r}function r(e){return e.toString().substring(2,e.toString().length-2).replace(/\.\*\?$/,"*")}return t.debug=t,t.default=t,t.coerce=function(e){if(e instanceof Error)return e.stack||e.message;return e},t.disable=function(){const e=[...t.names.map(r),...t.skips.map(r).map((e=>"-"+e))].join(",");return t.enable(""),e},t.enable=function(e){let n;t.save(e),t.namespaces=e,t.names=[],t.skips=[];const r=("string"==typeof e?e:"").split(/[\s,]+/),u=r.length;for(n=0;n{t[n]=e[n]})),t.names=[],t.skips=[],t.formatters={},t.selectColor=function(e){let n=0;for(let t=0;t{const n=e.startsWith("-")?"":1===e.length?"-":"--",r=t.indexOf(n+e),u=t.indexOf("--");return-1!==r&&(-1===u||r{}),"Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."),t.colors=[6,2,3,4,5,1];try{const e=function(){if($r)return jr;$r=1;const e=E.default,t=A.default,n=Vr(),{env:r}=process;let u;function o(e){return 0!==e&&{level:e,hasBasic:!0,has256:e>=2,has16m:e>=3}}function i(t,o){if(0===u)return 0;if(n("color=16m")||n("color=full")||n("color=truecolor"))return 3;if(n("color=256"))return 2;if(t&&!o&&void 0===u)return 0;const i=u||0;if("dumb"===r.TERM)return i;if("win32"===process.platform){const t=e.release().split(".");return Number(t[0])>=10&&Number(t[2])>=10586?Number(t[2])>=14931?3:2:1}if("CI"in r)return["TRAVIS","CIRCLECI","APPVEYOR","GITLAB_CI","GITHUB_ACTIONS","BUILDKITE"].some((e=>e in r))||"codeship"===r.CI_NAME?1:i;if("TEAMCITY_VERSION"in r)return/^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(r.TEAMCITY_VERSION)?1:0;if("truecolor"===r.COLORTERM)return 3;if("TERM_PROGRAM"in r){const e=parseInt((r.TERM_PROGRAM_VERSION||"").split(".")[0],10);switch(r.TERM_PROGRAM){case"iTerm.app":return e>=3?3:2;case"Apple_Terminal":return 2}}return/-256(color)?$/i.test(r.TERM)?2:/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(r.TERM)||"COLORTERM"in r?1:i}return n("no-color")||n("no-colors")||n("color=false")||n("color=never")?u=0:(n("color")||n("colors")||n("color=true")||n("color=always"))&&(u=1),"FORCE_COLOR"in r&&(u="true"===r.FORCE_COLOR?1:"false"===r.FORCE_COLOR?0:0===r.FORCE_COLOR.length?1:Math.min(parseInt(r.FORCE_COLOR,10),3)),jr={supportsColor:function(e){return o(i(e,e&&e.isTTY))},stdout:o(i(!0,t.isatty(1))),stderr:o(i(!0,t.isatty(2)))}}();e&&(e.stderr||e).level>=2&&(t.colors=[20,21,26,27,32,33,38,39,40,41,42,43,44,45,56,57,62,63,68,69,74,75,76,77,78,79,80,81,92,93,98,99,112,113,128,129,134,135,148,149,160,161,162,163,164,165,166,167,168,169,170,171,172,173,178,179,184,185,196,197,198,199,200,201,202,203,204,205,206,207,208,209,214,215,220,221])}catch(e){}t.inspectOpts=Object.keys(process.env).filter((e=>/^debug_/i.test(e))).reduce(((e,t)=>{const n=t.substring(6).toLowerCase().replace(/_([a-z])/g,((e,t)=>t.toUpperCase()));let r=process.env[t];return r=!!/^(yes|on|true|enabled)$/i.test(r)||!/^(no|off|false|disabled)$/i.test(r)&&("null"===r?null:Number(r)),e[n]=r,e}),{}),e.exports=Rr()(t);const{formatters:u}=e.exports;u.o=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts).split("\n").map((e=>e.trim())).join(" ")},u.O=function(e){return this.inspectOpts.colors=this.useColors,r.inspect(e,this.inspectOpts)}}(Gr,Gr.exports)),Gr.exports}Jr=Nr,"undefined"==typeof process||"renderer"===process.type||!0===process.browser||process.__nwjs?Jr.exports=(Br||(Br=1,function(e,t){t.formatArgs=function(t){if(t[0]=(this.useColors?"%c":"")+this.namespace+(this.useColors?" %c":" ")+t[0]+(this.useColors?"%c ":" ")+"+"+e.exports.humanize(this.diff),!this.useColors)return;const n="color: "+this.color;t.splice(1,0,n,"color: inherit");let r=0,u=0;t[0].replace(/%[a-zA-Z%]/g,(e=>{"%%"!==e&&(r++,"%c"===e&&(u=r))})),t.splice(u,0,n)},t.save=function(e){try{e?t.storage.setItem("debug",e):t.storage.removeItem("debug")}catch(e){}},t.load=function(){let e;try{e=t.storage.getItem("debug")}catch(e){}return!e&&"undefined"!=typeof process&&"env"in process&&(e=process.env.DEBUG),e},t.useColors=function(){return!("undefined"==typeof window||!window.process||"renderer"!==window.process.type&&!window.process.__nwjs)||("undefined"==typeof navigator||!navigator.userAgent||!navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/))&&("undefined"!=typeof document&&document.documentElement&&document.documentElement.style&&document.documentElement.style.WebkitAppearance||"undefined"!=typeof window&&window.console&&(window.console.firebug||window.console.exception&&window.console.table)||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)&&parseInt(RegExp.$1,10)>=31||"undefined"!=typeof navigator&&navigator.userAgent&&navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/))},t.storage=function(){try{return localStorage}catch(e){}}(),t.destroy=(()=>{let e=!1;return()=>{e||(e=!0,console.warn("Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`."))}})(),t.colors=["#0000CC","#0000FF","#0033CC","#0033FF","#0066CC","#0066FF","#0099CC","#0099FF","#00CC00","#00CC33","#00CC66","#00CC99","#00CCCC","#00CCFF","#3300CC","#3300FF","#3333CC","#3333FF","#3366CC","#3366FF","#3399CC","#3399FF","#33CC00","#33CC33","#33CC66","#33CC99","#33CCCC","#33CCFF","#6600CC","#6600FF","#6633CC","#6633FF","#66CC00","#66CC33","#9900CC","#9900FF","#9933CC","#9933FF","#99CC00","#99CC33","#CC0000","#CC0033","#CC0066","#CC0099","#CC00CC","#CC00FF","#CC3300","#CC3333","#CC3366","#CC3399","#CC33CC","#CC33FF","#CC6600","#CC6633","#CC9900","#CC9933","#CCCC00","#CCCC33","#FF0000","#FF0033","#FF0066","#FF0099","#FF00CC","#FF00FF","#FF3300","#FF3333","#FF3366","#FF3399","#FF33CC","#FF33FF","#FF6600","#FF6633","#FF9900","#FF9933","#FFCC00","#FFCC33"],t.log=console.debug||console.log||(()=>{}),e.exports=Rr()(t);const{formatters:n}=e.exports;n.j=function(e){try{return JSON.stringify(e)}catch(e){return"[UnexpectedJSONParseError]: "+e.message}}}(Ir,Ir.exports)),Ir.exports):Jr.exports=Ur();var Wr=function(e){return(e=e||{}).circles?function(e){var t=[],n=[];return e.proto?function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o}:function e(u){if("object"!=typeof u||null===u)return u;if(u instanceof Date)return new Date(u);if(Array.isArray(u))return r(u,e);if(u instanceof Map)return new Map(r(Array.from(u),e));if(u instanceof Set)return new Set(r(Array.from(u),e));var o={};for(var i in t.push(u),n.push(o),u)if(!1!==Object.hasOwnProperty.call(u,i)){var s=u[i];if("object"!=typeof s||null===s)o[i]=s;else if(s instanceof Date)o[i]=new Date(s);else if(s instanceof Map)o[i]=new Map(r(Array.from(s),e));else if(s instanceof Set)o[i]=new Set(r(Array.from(s),e));else if(ArrayBuffer.isView(s))o[i]=zr(s);else{var c=t.indexOf(s);o[i]=-1!==c?n[c]:e(s)}}return t.pop(),n.pop(),o};function r(e,r){for(var u=Object.keys(e),o=new Array(u.length),i=0;i!e,Qr=e=>e&&"object"==typeof e&&!Array.isArray(e),eu=(e,t,n)=>{(Array.isArray(t)?t:[t]).forEach((t=>{if(t)throw new Error(`Problem with log4js configuration: (${Kr.inspect(e,{depth:5})}) - ${n}`)}))};var tu={configure:e=>{qr("New configuration to be validated: ",e),eu(e,Zr(Qr(e)),"must be an object."),qr(`Calling pre-processing listeners (${Yr.length})`),Yr.forEach((t=>t(e))),qr("Configuration pre-processing finished."),qr(`Calling configuration listeners (${Xr.length})`),Xr.forEach((t=>t(e))),qr("Configuration finished.")},addListener:e=>{Xr.push(e),qr(`Added listener, now ${Xr.length} listeners`)},addPreProcessingListener:e=>{Yr.push(e),qr(`Added pre-processing listener, now ${Yr.length} listeners`)},throwExceptionIf:eu,anObject:Qr,anInteger:e=>e&&"number"==typeof e&&Number.isInteger(e),validIdentifier:e=>/^[A-Za-z][A-Za-z0-9_]*$/g.test(e),not:Zr},nu={exports:{}};!function(e){function t(e,t){for(var n=e.toString();n.length-1?s:c,l=n(u.getHours()),f=n(u.getMinutes()),d=n(u.getSeconds()),D=t(u.getMilliseconds(),3),p=function(e){var t=Math.abs(e),n=String(Math.floor(t/60)),r=String(t%60);return n=("0"+n).slice(-2),r=("0"+r).slice(-2),0===e?"Z":(e<0?"+":"-")+n+":"+r}(u.getTimezoneOffset());return r.replace(/dd/g,o).replace(/MM/g,i).replace(/y{1,4}/g,a).replace(/hh/g,l).replace(/mm/g,f).replace(/ss/g,d).replace(/SSS/g,D).replace(/O/g,p)}function u(e,t,n,r){e["set"+(r?"":"UTC")+t](n)}e.exports=r,e.exports.asString=r,e.exports.parse=function(t,n,r){if(!t)throw new Error("pattern must be supplied");return function(t,n,r){var o=t.indexOf("O")<0,i=!1,s=[{pattern:/y{1,4}/,regexp:"\\d{1,4}",fn:function(e,t){u(e,"FullYear",t,o)}},{pattern:/MM/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Month",t-1,o),e.getMonth()!==t-1&&(i=!0)}},{pattern:/dd/,regexp:"\\d{1,2}",fn:function(e,t){i&&u(e,"Month",e.getMonth()-1,o),u(e,"Date",t,o)}},{pattern:/hh/,regexp:"\\d{1,2}",fn:function(e,t){u(e,"Hours",t,o)}},{pattern:/mm/,regexp:"\\d\\d",fn:function(e,t){u(e,"Minutes",t,o)}},{pattern:/ss/,regexp:"\\d\\d",fn:function(e,t){u(e,"Seconds",t,o)}},{pattern:/SSS/,regexp:"\\d\\d\\d",fn:function(e,t){u(e,"Milliseconds",t,o)}},{pattern:/O/,regexp:"[+-]\\d{1,2}:?\\d{2}?|Z",fn:function(e,t){t="Z"===t?0:t.replace(":","");var n=Math.abs(t),r=(t>0?-1:1)*(n%100+60*Math.floor(n/100));e.setUTCMinutes(e.getUTCMinutes()+r)}}],c=s.reduce((function(e,t){return t.pattern.test(e.regexp)?(t.index=e.regexp.match(t.pattern).index,e.regexp=e.regexp.replace(t.pattern,"("+t.regexp+")")):t.index=-1,e}),{regexp:t,index:[]}),a=s.filter((function(e){return e.index>-1}));a.sort((function(e,t){return e.index-t.index}));var l=new RegExp(c.regexp).exec(n);if(l){var f=r||e.exports.now();return a.forEach((function(e,t){e.fn(f,l[t+1])})),f}throw new Error("String '"+n+"' could not be parsed as '"+t+"'")}(t,n,r)},e.exports.now=function(){return new Date},e.exports.ISO8601_FORMAT="yyyy-MM-ddThh:mm:ss.SSS",e.exports.ISO8601_WITH_TZ_OFFSET_FORMAT="yyyy-MM-ddThh:mm:ss.SSSO",e.exports.DATETIME_FORMAT="dd MM yyyy hh:mm:ss.SSS",e.exports.ABSOLUTETIME_FORMAT="hh:mm:ss.SSS"}(nu);const ru=nu.exports,uu=E.default,ou=F.default,iu=p.default,su={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[90,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[91,39],yellow:[33,39]};function cu(e){return e?`[${su[e][0]}m`:""}function au(e){return e?`[${su[e][1]}m`:""}function lu(e,t){return n=ou.format("[%s] [%s] %s - ",ru.asString(e.startTime),e.level.toString(),e.categoryName),cu(r=t)+n+au(r);var n,r}function fu(e){return lu(e)+ou.format(...e.data)}function du(e){return lu(e,e.level.colour)+ou.format(...e.data)}function Du(e){return ou.format(...e.data)}function pu(e){return e.data[0]}function Eu(e,t){const n=/%(-?[0-9]+)?(\.?-?[0-9]+)?([[\]cdhmnprzxXyflos%])(\{([^}]+)\})?|([^%]+)/;function r(e){return e&&e.pid?e.pid.toString():process.pid.toString()}e=e||"%r %p %c - %m%n";const u={c:function(e,t){let n=e.categoryName;if(t){const e=parseInt(t,10),r=n.split(".");ee&&(n=r.slice(-e).join(iu.sep))}return n},l:function(e){return e.lineNumber?`${e.lineNumber}`:""},o:function(e){return e.columnNumber?`${e.columnNumber}`:""},s:function(e){return e.callStack||""}};function o(e,t,n){return u[e](t,n)}function i(e,t,n){let r=e;return r=function(e,t){let n;return e?(n=parseInt(e.substr(1),10),n>0?t.slice(0,n):t.slice(n)):t}(t,r),r=function(e,t){let n;if(e)if("-"===e.charAt(0))for(n=parseInt(e.substr(1),10);t.lengthDu,basic:()=>fu,colored:()=>du,coloured:()=>du,pattern:e=>Eu(e&&e.pattern,e&&e.tokens),dummy:()=>pu};var hu={basicLayout:fu,messagePassThroughLayout:Du,patternLayout:Eu,colouredLayout:du,coloredLayout:du,dummyLayout:pu,addLayout(e,t){mu[e]=t},layout:(e,t)=>mu[e]&&mu[e](t)};const yu=tu,Cu=["white","grey","black","blue","cyan","green","magenta","red","yellow"];class Fu{constructor(e,t,n){this.level=e,this.levelStr=t,this.colour=n}toString(){return this.levelStr}static getLevel(e,t){return e?e instanceof Fu?e:(e instanceof Object&&e.levelStr&&(e=e.levelStr),Fu[e.toString().toUpperCase()]||t):t}static addLevels(e){if(e){Object.keys(e).forEach((t=>{const n=t.toUpperCase();Fu[n]=new Fu(e[t].value,n,e[t].colour);const r=Fu.levels.findIndex((e=>e.levelStr===n));r>-1?Fu.levels[r]=Fu[n]:Fu.levels.push(Fu[n])})),Fu.levels.sort(((e,t)=>e.level-t.level))}}isLessThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level<=e.level}isGreaterThanOrEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level>=e.level}isEqualTo(e){return"string"==typeof e&&(e=Fu.getLevel(e)),this.level===e.level}}Fu.levels=[],Fu.addLevels({ALL:{value:Number.MIN_VALUE,colour:"grey"},TRACE:{value:5e3,colour:"blue"},DEBUG:{value:1e4,colour:"cyan"},INFO:{value:2e4,colour:"green"},WARN:{value:3e4,colour:"yellow"},ERROR:{value:4e4,colour:"red"},FATAL:{value:5e4,colour:"magenta"},MARK:{value:9007199254740992,colour:"grey"},OFF:{value:Number.MAX_VALUE,colour:"grey"}}),yu.addListener((e=>{const t=e.levels;if(t){yu.throwExceptionIf(e,yu.not(yu.anObject(t)),"levels must be an object");Object.keys(t).forEach((n=>{yu.throwExceptionIf(e,yu.not(yu.validIdentifier(n)),`level name "${n}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`),yu.throwExceptionIf(e,yu.not(yu.anObject(t[n])),`level "${n}" must be an object`),yu.throwExceptionIf(e,yu.not(t[n].value),`level "${n}" must have a 'value' property`),yu.throwExceptionIf(e,yu.not(yu.anInteger(t[n].value)),`level "${n}".value must have an integer value`),yu.throwExceptionIf(e,yu.not(t[n].colour),`level "${n}" must have a 'colour' property`),yu.throwExceptionIf(e,yu.not(Cu.indexOf(t[n].colour)>-1),`level "${n}".colour must be one of ${Cu.join(", ")}`)}))}})),yu.addListener((e=>{Fu.addLevels(e.levels)}));var gu=Fu,Au={exports:{}},vu={};/*! (c) 2020 Andrea Giammarchi */ +const{parse:Su,stringify:wu}=JSON,{keys:Ou}=Object,bu=String,_u="string",Bu={},Pu="object",ku=(e,t)=>t,xu=e=>e instanceof bu?bu(e):e,Nu=(e,t)=>typeof t===_u?new bu(t):t,Iu=(e,t,n,r)=>{const u=[];for(let o=Ou(n),{length:i}=o,s=0;s{const r=bu(t.push(n)-1);return e.set(n,r),r},Ru=(e,t)=>{const n=Su(e,Nu).map(xu),r=n[0],u=t||ku,o=typeof r===Pu&&r?Iu(n,new Set,r,u):r;return u.call({"":o},"",o)};vu.parse=Ru;const Mu=(e,t,n)=>{const r=t&&typeof t===Pu?(e,n)=>""===e||-1Su(Mu(e));vu.fromJSON=e=>Ru(wu(e));const Lu=vu,ju=gu;class $u{constructor(e,t,n,r,u){this.startTime=new Date,this.categoryName=e,this.data=n,this.level=t,this.context=Object.assign({},r),this.pid=process.pid,u&&(this.functionName=u.functionName,this.fileName=u.fileName,this.lineNumber=u.lineNumber,this.columnNumber=u.columnNumber,this.callStack=u.callStack)}serialise(){const e=this.data.map((e=>(e&&e.message&&e.stack&&(e=Object.assign({message:e.message,stack:e.stack},e)),e)));return this.data=e,Lu.stringify(this)}static deserialise(e){let t;try{const n=Lu.parse(e);n.data=n.data.map((e=>{if(e&&e.message&&e.stack){const t=new Error(e);Object.keys(e).forEach((n=>{t[n]=e[n]})),e=t}return e})),t=new $u(n.categoryName,ju.getLevel(n.level.levelStr),n.data,n.context),t.startTime=new Date(n.startTime),t.pid=n.pid,t.cluster=n.cluster}catch(n){t=new $u("log4js",ju.ERROR,["Unable to parse log:",e,"because: ",n])}return t}}var Hu=$u;const Ju=Nr.exports("log4js:clustering"),Gu=Hu,Vu=tu;let Uu=!1,Wu=null;try{Wu=require("cluster")}catch(e){Ju("cluster module not present"),Uu=!0}const zu=[];let Ku=!1,qu="NODE_APP_INSTANCE";const Yu=()=>Ku&&"0"===process.env[qu],Xu=()=>Uu||Wu.isMaster||Yu(),Zu=e=>{zu.forEach((t=>t(e)))},Qu=(e,t)=>{if(Ju("cluster message received from worker ",e,": ",t),e.topic&&e.data&&(t=e,e=void 0),t&&t.topic&&"log4js:message"===t.topic){Ju("received message: ",t.data);const e=Gu.deserialise(t.data);Zu(e)}};Uu||Vu.addListener((e=>{zu.length=0,({pm2:Ku,disableClustering:Uu,pm2InstanceVar:qu="NODE_APP_INSTANCE"}=e),Ju(`clustering disabled ? ${Uu}`),Ju(`cluster.isMaster ? ${Wu&&Wu.isMaster}`),Ju(`pm2 enabled ? ${Ku}`),Ju(`pm2InstanceVar = ${qu}`),Ju(`process.env[${qu}] = ${process.env[qu]}`),Ku&&process.removeListener("message",Qu),Wu&&Wu.removeListener&&Wu.removeListener("message",Qu),Uu||e.disableClustering?Ju("Not listening for cluster messages, because clustering disabled."):Yu()?(Ju("listening for PM2 broadcast messages"),process.on("message",Qu)):Wu.isMaster?(Ju("listening for cluster messages"),Wu.on("message",Qu)):Ju("not listening for messages, because we are not a master process")}));var eo={onlyOnMaster:(e,t)=>Xu()?e():t,isMaster:Xu,send:e=>{Xu()?Zu(e):(Ku||(e.cluster={workerId:Wu.worker.id,worker:process.pid}),process.send({topic:"log4js:message",data:e.serialise()}))},onMessage:e=>{zu.push(e)}},to={};function no(e){if("number"==typeof e&&Number.isInteger(e))return e;const t={K:1024,M:1048576,G:1073741824},n=Object.keys(t),r=e.substr(e.length-1).toLocaleUpperCase(),u=e.substring(0,e.length-1).trim();if(n.indexOf(r)<0||!Number.isInteger(Number(u)))throw Error(`maxLogSize: "${e}" is invalid`);return u*t[r]}function ro(e){return function(e,t){const n=Object.assign({},t);return Object.keys(e).forEach((r=>{n[r]&&(n[r]=e[r](t[r]))})),n}({maxLogSize:no},e)}const uo={file:ro,fileSync:ro};to.modifyConfig=e=>uo[e.type]?uo[e.type](e):e;var oo={};const io=console.log.bind(console);oo.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{io(e(n,t))}}(n,e.timezoneOffset)};var so={};so.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stdout.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var co={};co.configure=function(e,t){let n=t.colouredLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){return n=>{process.stderr.write(`${e(n,t)}\n`)}}(n,e.timezoneOffset)};var ao={};ao.configure=function(e,t,n,r){const u=n(e.appender);return function(e,t,n,r){const u=r.getLevel(e),o=r.getLevel(t,r.FATAL);return e=>{const t=e.level;t.isGreaterThanOrEqualTo(u)&&t.isLessThanOrEqualTo(o)&&n(e)}}(e.level,e.maxLevel,u,r)};var lo={};const fo=Nr.exports("log4js:categoryFilter");lo.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return"string"==typeof e&&(e=[e]),n=>{fo(`Checking ${n.categoryName} against ${e}`),-1===e.indexOf(n.categoryName)&&(fo("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Do={};const po=Nr.exports("log4js:noLogFilter");Do.configure=function(e,t,n){const r=n(e.appender);return function(e,t){return n=>{po(`Checking data: ${n.data} against filters: ${e}`),"string"==typeof e&&(e=[e]),e=e.filter((e=>null!=e&&""!==e));const r=new RegExp(e.join("|"),"i");(0===e.length||n.data.findIndex((e=>r.test(e)))<0)&&(po("Not excluded, sending to appender"),t(n))}}(e.exclude,r)};var Eo={},mo={exports:{}},ho={},yo={fromCallback:function(e){return Object.defineProperty((function(){if("function"!=typeof arguments[arguments.length-1])return new Promise(((t,n)=>{arguments[arguments.length]=(e,r)=>{if(e)return n(e);t(r)},arguments.length++,e.apply(this,arguments)}));e.apply(this,arguments)}),"name",{value:e.name})},fromPromise:function(e){return Object.defineProperty((function(){const t=arguments[arguments.length-1];if("function"!=typeof t)return e.apply(this,arguments);e.apply(this,arguments).then((e=>t(null,e)),t)}),"name",{value:e.name})}};!function(e){const t=yo.fromCallback,n=we,r=["access","appendFile","chmod","chown","close","copyFile","fchmod","fchown","fdatasync","fstat","fsync","ftruncate","futimes","lchown","lchmod","link","lstat","mkdir","mkdtemp","open","readFile","readdir","readlink","realpath","rename","rmdir","stat","symlink","truncate","unlink","utimes","writeFile"].filter((e=>"function"==typeof n[e]));Object.keys(n).forEach((t=>{"promises"!==t&&(e[t]=n[t])})),r.forEach((r=>{e[r]=t(n[r])})),e.exists=function(e,t){return"function"==typeof t?n.exists(e,t):new Promise((t=>n.exists(e,t)))},e.read=function(e,t,r,u,o,i){return"function"==typeof i?n.read(e,t,r,u,o,i):new Promise(((i,s)=>{n.read(e,t,r,u,o,((e,t,n)=>{if(e)return s(e);i({bytesRead:t,buffer:n})}))}))},e.write=function(e,t,...r){return"function"==typeof r[r.length-1]?n.write(e,t,...r):new Promise(((u,o)=>{n.write(e,t,...r,((e,t,n)=>{if(e)return o(e);u({bytesWritten:t,buffer:n})}))}))},"function"==typeof n.realpath.native&&(e.realpath.native=t(n.realpath.native))}(ho);const Co=p.default;function Fo(e){return(e=Co.normalize(Co.resolve(e)).split(Co.sep)).length>0?e[0]:null}const go=/[<>:"|?*]/;var Ao=function(e){const t=Fo(e);return e=e.replace(t,""),go.test(e)};const vo=we,So=p.default,wo=Ao,Oo=parseInt("0777",8);var bo=function e(t,n,r,u){if("function"==typeof n?(r=n,n={}):n&&"object"==typeof n||(n={mode:n}),"win32"===process.platform&&wo(t)){const e=new Error(t+" contains invalid WIN32 path characters.");return e.code="EINVAL",r(e)}let o=n.mode;const i=n.fs||vo;void 0===o&&(o=Oo&~process.umask()),u||(u=null),r=r||function(){},t=So.resolve(t),i.mkdir(t,o,(o=>{if(!o)return r(null,u=u||t);if("ENOENT"===o.code){if(So.dirname(t)===t)return r(o);e(So.dirname(t),n,((u,o)=>{u?r(u,o):e(t,n,r,o)}))}else i.stat(t,((e,t)=>{e||!t.isDirectory()?r(o,u):r(null,u)}))}))};const _o=we,Bo=p.default,Po=Ao,ko=parseInt("0777",8);var xo=function e(t,n,r){n&&"object"==typeof n||(n={mode:n});let u=n.mode;const o=n.fs||_o;if("win32"===process.platform&&Po(t)){const e=new Error(t+" contains invalid WIN32 path characters.");throw e.code="EINVAL",e}void 0===u&&(u=ko&~process.umask()),r||(r=null),t=Bo.resolve(t);try{o.mkdirSync(t,u),r=r||t}catch(u){if("ENOENT"===u.code){if(Bo.dirname(t)===t)throw u;r=e(Bo.dirname(t),n,r),e(t,n,r)}else{let e;try{e=o.statSync(t)}catch(e){throw u}if(!e.isDirectory())throw u}}return r};const No=(0,yo.fromCallback)(bo);var Io={mkdirs:No,mkdirsSync:xo,mkdirp:No,mkdirpSync:xo,ensureDir:No,ensureDirSync:xo};const To=we;E.default,p.default;var Ro=function(e,t,n,r){To.open(e,"r+",((e,u)=>{if(e)return r(e);To.futimes(u,t,n,(e=>{To.close(u,(t=>{r&&r(e||t)}))}))}))},Mo=function(e,t,n){const r=To.openSync(e,"r+");return To.futimesSync(r,t,n),To.closeSync(r)};const Lo=we,jo=p.default,$o=10,Ho=5,Jo=0,Go=process.versions.node.split("."),Vo=Number.parseInt(Go[0],10),Uo=Number.parseInt(Go[1],10),Wo=Number.parseInt(Go[2],10);function zo(){if(Vo>$o)return!0;if(Vo===$o){if(Uo>Ho)return!0;if(Uo===Ho&&Wo>=Jo)return!0}return!1}function Ko(e,t){const n=jo.resolve(e).split(jo.sep).filter((e=>e)),r=jo.resolve(t).split(jo.sep).filter((e=>e));return n.reduce(((e,t,n)=>e&&r[n]===t),!0)}function qo(e,t,n){return`Cannot ${n} '${e}' to a subdirectory of itself, '${t}'.`}var Yo,Xo,Zo={checkPaths:function(e,t,n,r){!function(e,t,n){zo()?Lo.stat(e,{bigint:!0},((e,r)=>{if(e)return n(e);Lo.stat(t,{bigint:!0},((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))})):Lo.stat(e,((e,r)=>{if(e)return n(e);Lo.stat(t,((e,t)=>e?"ENOENT"===e.code?n(null,{srcStat:r,destStat:null}):n(e):n(null,{srcStat:r,destStat:t})))}))}(e,t,((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;return s&&s.ino&&s.dev&&s.ino===i.ino&&s.dev===i.dev?r(new Error("Source and destination must not be the same.")):i.isDirectory()&&Ko(e,t)?r(new Error(qo(e,t,n))):r(null,{srcStat:i,destStat:s})}))},checkPathsSync:function(e,t,n){const{srcStat:r,destStat:u}=function(e,t){let n,r;n=zo()?Lo.statSync(e,{bigint:!0}):Lo.statSync(e);try{r=zo()?Lo.statSync(t,{bigint:!0}):Lo.statSync(t)}catch(e){if("ENOENT"===e.code)return{srcStat:n,destStat:null};throw e}return{srcStat:n,destStat:r}}(e,t);if(u&&u.ino&&u.dev&&u.ino===r.ino&&u.dev===r.dev)throw new Error("Source and destination must not be the same.");if(r.isDirectory()&&Ko(e,t))throw new Error(qo(e,t,n));return{srcStat:r,destStat:u}},checkParentPaths:function e(t,n,r,u,o){const i=jo.resolve(jo.dirname(t)),s=jo.resolve(jo.dirname(r));if(s===i||s===jo.parse(s).root)return o();zo()?Lo.stat(s,{bigint:!0},((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o))):Lo.stat(s,((i,c)=>i?"ENOENT"===i.code?o():o(i):c.ino&&c.dev&&c.ino===n.ino&&c.dev===n.dev?o(new Error(qo(t,r,u))):e(t,n,s,u,o)))},checkParentPathsSync:function e(t,n,r,u){const o=jo.resolve(jo.dirname(t)),i=jo.resolve(jo.dirname(r));if(i===o||i===jo.parse(i).root)return;let s;try{s=zo()?Lo.statSync(i,{bigint:!0}):Lo.statSync(i)}catch(e){if("ENOENT"===e.code)return;throw e}if(s.ino&&s.dev&&s.ino===n.ino&&s.dev===n.dev)throw new Error(qo(t,r,u));return e(t,n,i,u)},isSrcSubdir:Ko};const Qo=we,ei=p.default,ti=Io.mkdirsSync,ni=Mo,ri=Zo;function ui(e,t,n,r){if(!r.filter||r.filter(t,n))return function(e,t,n,r){const u=r.dereference?Qo.statSync:Qo.lstatSync,o=u(t);if(o.isDirectory())return function(e,t,n,r,u){if(!t)return function(e,t,n,r){return Qo.mkdirSync(n),ii(t,n,r),Qo.chmodSync(n,e.mode)}(e,n,r,u);if(t&&!t.isDirectory())throw new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`);return ii(n,r,u)}(o,e,t,n,r);if(o.isFile()||o.isCharacterDevice()||o.isBlockDevice())return function(e,t,n,r,u){return t?function(e,t,n,r){if(r.overwrite)return Qo.unlinkSync(n),oi(e,t,n,r);if(r.errorOnExist)throw new Error(`'${n}' already exists`)}(e,n,r,u):oi(e,n,r,u)}(o,e,t,n,r);if(o.isSymbolicLink())return function(e,t,n,r){let u=Qo.readlinkSync(t);r.dereference&&(u=ei.resolve(process.cwd(),u));if(e){let e;try{e=Qo.readlinkSync(n)}catch(e){if("EINVAL"===e.code||"UNKNOWN"===e.code)return Qo.symlinkSync(u,n);throw e}if(r.dereference&&(e=ei.resolve(process.cwd(),e)),ri.isSrcSubdir(u,e))throw new Error(`Cannot copy '${u}' to a subdirectory of itself, '${e}'.`);if(Qo.statSync(n).isDirectory()&&ri.isSrcSubdir(e,u))throw new Error(`Cannot overwrite '${e}' with '${u}'.`);return function(e,t){return Qo.unlinkSync(t),Qo.symlinkSync(e,t)}(u,n)}return Qo.symlinkSync(u,n)}(e,t,n,r)}(e,t,n,r)}function oi(e,t,n,r){return"function"==typeof Qo.copyFileSync?(Qo.copyFileSync(t,n),Qo.chmodSync(n,e.mode),r.preserveTimestamps?ni(n,e.atime,e.mtime):void 0):function(e,t,n,r){const u=65536,o=(Xo?Yo:(Xo=1,Yo=function(e){if("function"==typeof Buffer.allocUnsafe)try{return Buffer.allocUnsafe(e)}catch(t){return new Buffer(e)}return new Buffer(e)}))(u),i=Qo.openSync(t,"r"),s=Qo.openSync(n,"w",e.mode);let c=0;for(;cfunction(e,t,n,r){const u=ei.join(t,e),o=ei.join(n,e),{destStat:i}=ri.checkPathsSync(u,o,"copy");return ui(i,u,o,r)}(r,e,t,n)))}var si=function(e,t,n){"function"==typeof n&&(n={filter:n}),(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269");const{srcStat:r,destStat:u}=ri.checkPathsSync(e,t,"copy");return ri.checkParentPathsSync(e,r,t,"copy"),function(e,t,n,r){if(r.filter&&!r.filter(t,n))return;const u=ei.dirname(n);Qo.existsSync(u)||ti(u);return ui(e,t,n,r)}(u,e,t,n)},ci={copySync:si};const ai=yo.fromPromise,li=ho;var fi={pathExists:ai((function(e){return li.access(e).then((()=>!0)).catch((()=>!1))})),pathExistsSync:li.existsSync};const di=we,Di=p.default,pi=Io.mkdirs,Ei=fi.pathExists,mi=Ro,hi=Zo;function yi(e,t,n,r,u){const o=Di.dirname(n);Ei(o,((i,s)=>i?u(i):s?Fi(e,t,n,r,u):void pi(o,(o=>o?u(o):Fi(e,t,n,r,u)))))}function Ci(e,t,n,r,u,o){Promise.resolve(u.filter(n,r)).then((i=>i?e(t,n,r,u,o):o()),(e=>o(e)))}function Fi(e,t,n,r,u){return r.filter?Ci(gi,e,t,n,r,u):gi(e,t,n,r,u)}function gi(e,t,n,r,u){(r.dereference?di.stat:di.lstat)(t,((o,i)=>o?u(o):i.isDirectory()?function(e,t,n,r,u,o){if(!t)return function(e,t,n,r,u){di.mkdir(n,(o=>{if(o)return u(o);Si(t,n,r,(t=>t?u(t):di.chmod(n,e.mode,u)))}))}(e,n,r,u,o);if(t&&!t.isDirectory())return o(new Error(`Cannot overwrite non-directory '${r}' with directory '${n}'.`));return Si(n,r,u,o)}(i,e,t,n,r,u):i.isFile()||i.isCharacterDevice()||i.isBlockDevice()?function(e,t,n,r,u,o){return t?function(e,t,n,r,u){if(!r.overwrite)return r.errorOnExist?u(new Error(`'${n}' already exists`)):u();di.unlink(n,(o=>o?u(o):Ai(e,t,n,r,u)))}(e,n,r,u,o):Ai(e,n,r,u,o)}(i,e,t,n,r,u):i.isSymbolicLink()?function(e,t,n,r,u){di.readlink(t,((t,o)=>t?u(t):(r.dereference&&(o=Di.resolve(process.cwd(),o)),e?void di.readlink(n,((t,i)=>t?"EINVAL"===t.code||"UNKNOWN"===t.code?di.symlink(o,n,u):u(t):(r.dereference&&(i=Di.resolve(process.cwd(),i)),hi.isSrcSubdir(o,i)?u(new Error(`Cannot copy '${o}' to a subdirectory of itself, '${i}'.`)):e.isDirectory()&&hi.isSrcSubdir(i,o)?u(new Error(`Cannot overwrite '${i}' with '${o}'.`)):function(e,t,n){di.unlink(t,(r=>r?n(r):di.symlink(e,t,n)))}(o,n,u)))):di.symlink(o,n,u))))}(e,t,n,r,u):void 0))}function Ai(e,t,n,r,u){return"function"==typeof di.copyFile?di.copyFile(t,n,(t=>t?u(t):vi(e,n,r,u))):function(e,t,n,r,u){const o=di.createReadStream(t);o.on("error",(e=>u(e))).once("open",(()=>{const t=di.createWriteStream(n,{mode:e.mode});t.on("error",(e=>u(e))).on("open",(()=>o.pipe(t))).once("close",(()=>vi(e,n,r,u)))}))}(e,t,n,r,u)}function vi(e,t,n,r){di.chmod(t,e.mode,(u=>u?r(u):n.preserveTimestamps?mi(t,e.atime,e.mtime,r):r()))}function Si(e,t,n,r){di.readdir(e,((u,o)=>u?r(u):wi(o,e,t,n,r)))}function wi(e,t,n,r,u){const o=e.pop();return o?function(e,t,n,r,u,o){const i=Di.join(n,t),s=Di.join(r,t);hi.checkPaths(i,s,"copy",((t,c)=>{if(t)return o(t);const{destStat:a}=c;Fi(a,i,s,u,(t=>t?o(t):wi(e,n,r,u,o)))}))}(e,o,t,n,r,u):u()}var Oi=function(e,t,n,r){"function"!=typeof n||r?"function"==typeof n&&(n={filter:n}):(r=n,n={}),r=r||function(){},(n=n||{}).clobber=!("clobber"in n)||!!n.clobber,n.overwrite="overwrite"in n?!!n.overwrite:n.clobber,n.preserveTimestamps&&"ia32"===process.arch&&console.warn("fs-extra: Using the preserveTimestamps option in 32-bit node is not recommended;\n\n see https://github.com/jprichardson/node-fs-extra/issues/269"),hi.checkPaths(e,t,"copy",((u,o)=>{if(u)return r(u);const{srcStat:i,destStat:s}=o;hi.checkParentPaths(e,i,t,"copy",(u=>u?r(u):n.filter?Ci(yi,s,e,t,n,r):yi(s,e,t,n,r)))}))};var bi={copy:(0,yo.fromCallback)(Oi)};const _i=we,Bi=p.default,Pi=g.default,ki="win32"===process.platform;function xi(e){["unlink","chmod","stat","lstat","rmdir","readdir"].forEach((t=>{e[t]=e[t]||_i[t],e[t+="Sync"]=e[t]||_i[t]})),e.maxBusyTries=e.maxBusyTries||3}function Ni(e,t,n){let r=0;"function"==typeof t&&(n=t,t={}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi.strictEqual(typeof n,"function","rimraf: callback function required"),Pi(t,"rimraf: invalid options argument provided"),Pi.strictEqual(typeof t,"object","rimraf: options should be object"),xi(t),Ii(e,t,(function u(o){if(o){if(("EBUSY"===o.code||"ENOTEMPTY"===o.code||"EPERM"===o.code)&&rIi(e,t,u)),100*r)}"ENOENT"===o.code&&(o=null)}n(o)}))}function Ii(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.lstat(e,((r,u)=>r&&"ENOENT"===r.code?n(null):r&&"EPERM"===r.code&&ki?Ti(e,t,r,n):u&&u.isDirectory()?Mi(e,t,r,n):void t.unlink(e,(r=>{if(r){if("ENOENT"===r.code)return n(null);if("EPERM"===r.code)return ki?Ti(e,t,r,n):Mi(e,t,r,n);if("EISDIR"===r.code)return Mi(e,t,r,n)}return n(r)}))))}function Ti(e,t,n,r){Pi(e),Pi(t),Pi("function"==typeof r),n&&Pi(n instanceof Error),t.chmod(e,438,(u=>{u?r("ENOENT"===u.code?null:n):t.stat(e,((u,o)=>{u?r("ENOENT"===u.code?null:n):o.isDirectory()?Mi(e,t,n,r):t.unlink(e,r)}))}))}function Ri(e,t,n){let r;Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.chmodSync(e,438)}catch(e){if("ENOENT"===e.code)return;throw n}try{r=t.statSync(e)}catch(e){if("ENOENT"===e.code)return;throw n}r.isDirectory()?ji(e,t,n):t.unlinkSync(e)}function Mi(e,t,n,r){Pi(e),Pi(t),n&&Pi(n instanceof Error),Pi("function"==typeof r),t.rmdir(e,(u=>{!u||"ENOTEMPTY"!==u.code&&"EEXIST"!==u.code&&"EPERM"!==u.code?u&&"ENOTDIR"===u.code?r(n):r(u):function(e,t,n){Pi(e),Pi(t),Pi("function"==typeof n),t.readdir(e,((r,u)=>{if(r)return n(r);let o,i=u.length;if(0===i)return t.rmdir(e,n);u.forEach((r=>{Ni(Bi.join(e,r),t,(r=>{if(!o)return r?n(o=r):void(0==--i&&t.rmdir(e,n))}))}))}))}(e,t,r)}))}function Li(e,t){let n;xi(t=t||{}),Pi(e,"rimraf: missing path"),Pi.strictEqual(typeof e,"string","rimraf: path should be a string"),Pi(t,"rimraf: missing options"),Pi.strictEqual(typeof t,"object","rimraf: options should be object");try{n=t.lstatSync(e)}catch(n){if("ENOENT"===n.code)return;"EPERM"===n.code&&ki&&Ri(e,t,n)}try{n&&n.isDirectory()?ji(e,t,null):t.unlinkSync(e)}catch(n){if("ENOENT"===n.code)return;if("EPERM"===n.code)return ki?Ri(e,t,n):ji(e,t,n);if("EISDIR"!==n.code)throw n;ji(e,t,n)}}function ji(e,t,n){Pi(e),Pi(t),n&&Pi(n instanceof Error);try{t.rmdirSync(e)}catch(r){if("ENOTDIR"===r.code)throw n;if("ENOTEMPTY"===r.code||"EEXIST"===r.code||"EPERM"===r.code)!function(e,t){if(Pi(e),Pi(t),t.readdirSync(e).forEach((n=>Li(Bi.join(e,n),t))),!ki){return t.rmdirSync(e,t)}{const n=Date.now();do{try{return t.rmdirSync(e,t)}catch(e){}}while(Date.now()-n<500)}}(e,t);else if("ENOENT"!==r.code)throw r}}var $i=Ni;Ni.sync=Li;const Hi=$i;var Ji={remove:(0,yo.fromCallback)(Hi),removeSync:Hi.sync};const Gi=yo.fromCallback,Vi=we,Ui=p.default,Wi=Io,zi=Ji,Ki=Gi((function(e,t){t=t||function(){},Vi.readdir(e,((n,r)=>{if(n)return Wi.mkdirs(e,t);r=r.map((t=>Ui.join(e,t))),function e(){const n=r.pop();if(!n)return t();zi.remove(n,(n=>{if(n)return t(n);e()}))}()}))}));function qi(e){let t;try{t=Vi.readdirSync(e)}catch(t){return Wi.mkdirsSync(e)}t.forEach((t=>{t=Ui.join(e,t),zi.removeSync(t)}))}var Yi={emptyDirSync:qi,emptydirSync:qi,emptyDir:Ki,emptydir:Ki};const Xi=yo.fromCallback,Zi=p.default,Qi=we,es=Io,ts=fi.pathExists;var ns={createFile:Xi((function(e,t){function n(){Qi.writeFile(e,"",(e=>{if(e)return t(e);t()}))}Qi.stat(e,((r,u)=>{if(!r&&u.isFile())return t();const o=Zi.dirname(e);ts(o,((e,r)=>e?t(e):r?n():void es.mkdirs(o,(e=>{if(e)return t(e);n()}))))}))})),createFileSync:function(e){let t;try{t=Qi.statSync(e)}catch(e){}if(t&&t.isFile())return;const n=Zi.dirname(e);Qi.existsSync(n)||es.mkdirsSync(n),Qi.writeFileSync(e,"")}};const rs=yo.fromCallback,us=p.default,os=we,is=Io,ss=fi.pathExists;var cs={createLink:rs((function(e,t,n){function r(e,t){os.link(e,t,(e=>{if(e)return n(e);n(null)}))}ss(t,((u,o)=>u?n(u):o?n(null):void os.lstat(e,(u=>{if(u)return u.message=u.message.replace("lstat","ensureLink"),n(u);const o=us.dirname(t);ss(o,((u,i)=>u?n(u):i?r(e,t):void is.mkdirs(o,(u=>{if(u)return n(u);r(e,t)}))))}))))})),createLinkSync:function(e,t){if(os.existsSync(t))return;try{os.lstatSync(e)}catch(e){throw e.message=e.message.replace("lstat","ensureLink"),e}const n=us.dirname(t);return os.existsSync(n)||is.mkdirsSync(n),os.linkSync(e,t)}};const as=p.default,ls=we,fs=fi.pathExists;var ds={symlinkPaths:function(e,t,n){if(as.isAbsolute(e))return ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:e})));{const r=as.dirname(t),u=as.join(r,e);return fs(u,((t,o)=>t?n(t):o?n(null,{toCwd:u,toDst:e}):ls.lstat(e,(t=>t?(t.message=t.message.replace("lstat","ensureSymlink"),n(t)):n(null,{toCwd:e,toDst:as.relative(r,e)})))))}},symlinkPathsSync:function(e,t){let n;if(as.isAbsolute(e)){if(n=ls.existsSync(e),!n)throw new Error("absolute srcpath does not exist");return{toCwd:e,toDst:e}}{const r=as.dirname(t),u=as.join(r,e);if(n=ls.existsSync(u),n)return{toCwd:u,toDst:e};if(n=ls.existsSync(e),!n)throw new Error("relative srcpath does not exist");return{toCwd:e,toDst:as.relative(r,e)}}}};const Ds=we;var ps={symlinkType:function(e,t,n){if(n="function"==typeof t?t:n,t="function"!=typeof t&&t)return n(null,t);Ds.lstat(e,((e,r)=>{if(e)return n(null,"file");t=r&&r.isDirectory()?"dir":"file",n(null,t)}))},symlinkTypeSync:function(e,t){let n;if(t)return t;try{n=Ds.lstatSync(e)}catch(e){return"file"}return n&&n.isDirectory()?"dir":"file"}};const Es=yo.fromCallback,ms=p.default,hs=we,ys=Io.mkdirs,Cs=Io.mkdirsSync,Fs=ds.symlinkPaths,gs=ds.symlinkPathsSync,As=ps.symlinkType,vs=ps.symlinkTypeSync,Ss=fi.pathExists;var ws={createSymlink:Es((function(e,t,n,r){r="function"==typeof n?n:r,n="function"!=typeof n&&n,Ss(t,((u,o)=>u?r(u):o?r(null):void Fs(e,t,((u,o)=>{if(u)return r(u);e=o.toDst,As(o.toCwd,n,((n,u)=>{if(n)return r(n);const o=ms.dirname(t);Ss(o,((n,i)=>n?r(n):i?hs.symlink(e,t,u,r):void ys(o,(n=>{if(n)return r(n);hs.symlink(e,t,u,r)}))))}))}))))})),createSymlinkSync:function(e,t,n){if(hs.existsSync(t))return;const r=gs(e,t);e=r.toDst,n=vs(r.toCwd,n);const u=ms.dirname(t);return hs.existsSync(u)||Cs(u),hs.symlinkSync(e,t,n)}};var Os,bs={createFile:ns.createFile,createFileSync:ns.createFileSync,ensureFile:ns.createFile,ensureFileSync:ns.createFileSync,createLink:cs.createLink,createLinkSync:cs.createLinkSync,ensureLink:cs.createLink,ensureLinkSync:cs.createLinkSync,createSymlink:ws.createSymlink,createSymlinkSync:ws.createSymlinkSync,ensureSymlink:ws.createSymlink,ensureSymlinkSync:ws.createSymlinkSync};try{Os=we}catch(e){Os=D.default}function _s(e,t){var n,r="\n";return"object"==typeof t&&null!==t&&(t.spaces&&(n=t.spaces),t.EOL&&(r=t.EOL)),JSON.stringify(e,t?t.replacer:null,n).replace(/\n/g,r)+r}function Bs(e){return Buffer.isBuffer(e)&&(e=e.toString("utf8")),e=e.replace(/^\uFEFF/,"")}var Ps={readFile:function(e,t,n){null==n&&(n=t,t={}),"string"==typeof t&&(t={encoding:t});var r=(t=t||{}).fs||Os,u=!0;"throws"in t&&(u=t.throws),r.readFile(e,t,(function(r,o){if(r)return n(r);var i;o=Bs(o);try{i=JSON.parse(o,t?t.reviver:null)}catch(t){return u?(t.message=e+": "+t.message,n(t)):n(null,null)}n(null,i)}))},readFileSync:function(e,t){"string"==typeof(t=t||{})&&(t={encoding:t});var n=t.fs||Os,r=!0;"throws"in t&&(r=t.throws);try{var u=n.readFileSync(e,t);return u=Bs(u),JSON.parse(u,t.reviver)}catch(t){if(r)throw t.message=e+": "+t.message,t;return null}},writeFile:function(e,t,n,r){null==r&&(r=n,n={});var u=(n=n||{}).fs||Os,o="";try{o=_s(t,n)}catch(e){return void(r&&r(e,null))}u.writeFile(e,o,n,r)},writeFileSync:function(e,t,n){var r=(n=n||{}).fs||Os,u=_s(t,n);return r.writeFileSync(e,u,n)}},ks=Ps;const xs=yo.fromCallback,Ns=ks;var Is={readJson:xs(Ns.readFile),readJsonSync:Ns.readFileSync,writeJson:xs(Ns.writeFile),writeJsonSync:Ns.writeFileSync};const Ts=p.default,Rs=Io,Ms=fi.pathExists,Ls=Is;var js=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=Ts.dirname(e);Ms(u,((o,i)=>o?r(o):i?Ls.writeJson(e,t,n,r):void Rs.mkdirs(u,(u=>{if(u)return r(u);Ls.writeJson(e,t,n,r)}))))};const $s=we,Hs=p.default,Js=Io,Gs=Is;var Vs=function(e,t,n){const r=Hs.dirname(e);$s.existsSync(r)||Js.mkdirsSync(r),Gs.writeJsonSync(e,t,n)};const Us=yo.fromCallback,Ws=Is;Ws.outputJson=Us(js),Ws.outputJsonSync=Vs,Ws.outputJSON=Ws.outputJson,Ws.outputJSONSync=Ws.outputJsonSync,Ws.writeJSON=Ws.writeJson,Ws.writeJSONSync=Ws.writeJsonSync,Ws.readJSON=Ws.readJson,Ws.readJSONSync=Ws.readJsonSync;var zs=Ws;const Ks=we,qs=p.default,Ys=ci.copySync,Xs=Ji.removeSync,Zs=Io.mkdirpSync,Qs=Zo;function ec(e,t,n){try{Ks.renameSync(e,t)}catch(r){if("EXDEV"!==r.code)throw r;return function(e,t,n){const r={overwrite:n,errorOnExist:!0};return Ys(e,t,r),Xs(e)}(e,t,n)}}var tc=function(e,t,n){const r=(n=n||{}).overwrite||n.clobber||!1,{srcStat:u}=Qs.checkPathsSync(e,t,"move");return Qs.checkParentPathsSync(e,u,t,"move"),Zs(qs.dirname(t)),function(e,t,n){if(n)return Xs(t),ec(e,t,n);if(Ks.existsSync(t))throw new Error("dest already exists.");return ec(e,t,n)}(e,t,r)},nc={moveSync:tc};const rc=we,uc=p.default,oc=bi.copy,ic=Ji.remove,sc=Io.mkdirp,cc=fi.pathExists,ac=Zo;function lc(e,t,n,r){rc.rename(e,t,(u=>u?"EXDEV"!==u.code?r(u):function(e,t,n,r){const u={overwrite:n,errorOnExist:!0};oc(e,t,u,(t=>t?r(t):ic(e,r)))}(e,t,n,r):r()))}var fc=function(e,t,n,r){"function"==typeof n&&(r=n,n={});const u=n.overwrite||n.clobber||!1;ac.checkPaths(e,t,"move",((n,o)=>{if(n)return r(n);const{srcStat:i}=o;ac.checkParentPaths(e,i,t,"move",(n=>{if(n)return r(n);sc(uc.dirname(t),(n=>n?r(n):function(e,t,n,r){if(n)return ic(t,(u=>u?r(u):lc(e,t,n,r)));cc(t,((u,o)=>u?r(u):o?r(new Error("dest already exists.")):lc(e,t,n,r)))}(e,t,u,r)))}))}))};var dc={move:(0,yo.fromCallback)(fc)};const Dc=yo.fromCallback,pc=we,Ec=p.default,mc=Io,hc=fi.pathExists;var yc={outputFile:Dc((function(e,t,n,r){"function"==typeof n&&(r=n,n="utf8");const u=Ec.dirname(e);hc(u,((o,i)=>o?r(o):i?pc.writeFile(e,t,n,r):void mc.mkdirs(u,(u=>{if(u)return r(u);pc.writeFile(e,t,n,r)}))))})),outputFileSync:function(e,...t){const n=Ec.dirname(e);if(pc.existsSync(n))return pc.writeFileSync(e,...t);mc.mkdirsSync(n),pc.writeFileSync(e,...t)}};!function(e){e.exports=Object.assign({},ho,ci,bi,Yi,bs,zs,Io,nc,dc,yc,fi,Ji);const t=D.default;Object.getOwnPropertyDescriptor(t,"promises")&&Object.defineProperty(e.exports,"promises",{get:()=>t.promises})}(mo);const Cc=Nr.exports("streamroller:fileNameFormatter"),Fc=p.default;const gc=Nr.exports("streamroller:fileNameParser"),Ac=nu.exports;const vc=Nr.exports("streamroller:moveAndMaybeCompressFile"),Sc=mo.exports,wc=v.default;var Oc=async(e,t,n)=>{if(n=function(e){const t={mode:parseInt("0600",8),compress:!1},n=Object.assign({},t,e);return vc(`_parseOption: moveAndMaybeCompressFile called with option=${JSON.stringify(n)}`),n}(n),e!==t){if(await Sc.pathExists(e))if(vc(`moveAndMaybeCompressFile: moving file from ${e} to ${t} ${n.compress?"with":"without"} compress`),n.compress)await new Promise(((r,u)=>{let o=!1;const i=Sc.createWriteStream(t,{mode:n.mode,flags:"wx"}).on("open",(()=>{o=!0;const t=Sc.createReadStream(e).on("open",(()=>{t.pipe(wc.createGzip()).pipe(i)})).on("error",(t=>{vc(`moveAndMaybeCompressFile: error reading ${e}`,t),i.destroy(t)}))})).on("finish",(()=>{vc(`moveAndMaybeCompressFile: finished compressing ${t}, deleting ${e}`),Sc.unlink(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error deleting ${e}, truncating instead`,t),Sc.truncate(e).then(r).catch((t=>{vc(`moveAndMaybeCompressFile: error truncating ${e}`,t),u(t)}))}))})).on("error",(e=>{o?(vc(`moveAndMaybeCompressFile: error writing ${t}, deleting`,e),Sc.unlink(t).then((()=>{u(e)})).catch((e=>{vc(`moveAndMaybeCompressFile: error deleting ${t}`,e),u(e)}))):(vc(`moveAndMaybeCompressFile: error creating ${t}`,e),u(e))}))})).catch((()=>{}));else{vc(`moveAndMaybeCompressFile: renaming ${e} to ${t}`);try{await Sc.move(e,t,{overwrite:!0})}catch(n){if(vc(`moveAndMaybeCompressFile: error renaming ${e} to ${t}`,n),"ENOENT"!==n.code){vc("moveAndMaybeCompressFile: trying copy+truncate instead");try{await Sc.copy(e,t,{overwrite:!0}),await Sc.truncate(e)}catch(e){vc("moveAndMaybeCompressFile: error copy+truncate",e)}}}}}else vc("moveAndMaybeCompressFile: source and target are the same, not doing anything")};const bc=Nr.exports("streamroller:RollingFileWriteStream"),_c=mo.exports,Bc=p.default,Pc=E.default,kc=()=>new Date,xc=nu.exports,{Writable:Nc}=C.default,Ic=({file:e,keepFileExt:t,needsIndex:n,alwaysIncludeDate:r,compress:u,fileNameSep:o})=>{let i=o||".";const s=Fc.join(e.dir,e.name),c=t=>t+e.ext,a=(e,t,r)=>!n&&r||!t?e:e+i+t,l=(e,t,n)=>(t>0||r)&&n?e+i+n:e,f=(e,t)=>t&&u?e+".gz":e,d=t?[l,a,c,f]:[c,l,a,f];return({date:e,index:t})=>(Cc(`_formatFileName: date=${e}, index=${t}`),d.reduce(((n,r)=>r(n,t,e)),s))},Tc=({file:e,keepFileExt:t,pattern:n,fileNameSep:r})=>{let u=r||".";const o="__NOT_MATCHING__";let i=[(e,t)=>e.endsWith(".gz")?(gc("it is gzipped"),t.isCompressed=!0,e.slice(0,-1*".gz".length)):e,t?t=>t.startsWith(e.name)&&t.endsWith(e.ext)?(gc("it starts and ends with the right things"),t.slice(e.name.length+1,-1*e.ext.length)):o:t=>t.startsWith(e.base)?(gc("it starts with the right things"),t.slice(e.base.length+1)):o,n?(e,t)=>{const r=e.split(u);let o=r[r.length-1];gc("items: ",r,", indexStr: ",o);let i=e;void 0!==o&&o.match(/^\d+$/)?(i=e.slice(0,-1*(o.length+1)),gc(`dateStr is ${i}`),n&&!i&&(i=o,o="0")):o="0";try{const r=Ac.parse(n,i,new Date(0,0));return Ac.asString(n,r)!==i?e:(t.index=parseInt(o,10),t.date=i,t.timestamp=r.getTime(),"")}catch(t){return gc(`Problem parsing ${i} as ${n}, error was: `,t),e}}:(e,t)=>e.match(/^\d+$/)?(gc("it has an index"),t.index=parseInt(e,10),""):e];return e=>{let t={filename:e,index:0,isCompressed:!1};return i.reduce(((e,n)=>n(e,t)),e)?null:t}},Rc=Oc;var Mc=class extends Nc{constructor(e,t){if(bc(`constructor: creating RollingFileWriteStream. path=${e}`),"string"!=typeof e||0===e.length)throw new Error(`Invalid filename: ${e}`);if(e.endsWith(Bc.sep))throw new Error(`Filename is a directory: ${e}`);0===e.indexOf(`~${Bc.sep}`)&&(e=e.replace("~",Pc.homedir())),super(t),this.options=this._parseOption(t),this.fileObject=Bc.parse(e),""===this.fileObject.dir&&(this.fileObject=Bc.parse(Bc.join(process.cwd(),e))),this.fileFormatter=Ic({file:this.fileObject,alwaysIncludeDate:this.options.alwaysIncludePattern,needsIndex:this.options.maxSize 0`)}else delete n.maxSize;if(n.numBackups||0===n.numBackups){if(n.numBackups<0)throw new Error(`options.numBackups (${n.numBackups}) should be >= 0`);if(n.numBackups>=Number.MAX_SAFE_INTEGER)throw new Error(`options.numBackups (${n.numBackups}) should be < Number.MAX_SAFE_INTEGER`);n.numToKeep=n.numBackups+1}else if(n.numToKeep<=0)throw new Error(`options.numToKeep (${n.numToKeep}) should be > 0`);return bc(`_parseOption: creating stream with option=${JSON.stringify(n)}`),n}_final(e){this.currentFileStream.end("",this.options.encoding,e)}_write(e,t,n){this._shouldRoll().then((()=>{bc(`_write: writing chunk. file=${this.currentFileStream.path} state=${JSON.stringify(this.state)} chunk=${e}`),this.currentFileStream.write(e,t,(t=>{this.state.currentSize+=e.length,n(t)}))}))}async _shouldRoll(){(this._dateChanged()||this._tooBig())&&(bc(`_shouldRoll: rolling because dateChanged? ${this._dateChanged()} or tooBig? ${this._tooBig()}`),await this._roll())}_dateChanged(){return this.state.currentDate&&this.state.currentDate!==xc(this.options.pattern,kc())}_tooBig(){return this.state.currentSize>=this.options.maxSize}_roll(){return bc("_roll: closing the current stream"),new Promise(((e,t)=>{this.currentFileStream.end("",this.options.encoding,(()=>{this._moveOldFiles().then(e).catch(t)}))}))}async _moveOldFiles(){const e=await this._getExistingFiles();for(let t=(this.state.currentDate?e.filter((e=>e.date===this.state.currentDate)):e).length;t>=0;t--){bc(`_moveOldFiles: i = ${t}`);const e=this.fileFormatter({date:this.state.currentDate,index:t}),n=this.fileFormatter({date:this.state.currentDate,index:t+1}),r={compress:this.options.compress&&0===t,mode:this.options.mode};await Rc(e,n,r)}this.state.currentSize=0,this.state.currentDate=this.state.currentDate?xc(this.options.pattern,kc()):null,bc(`_moveOldFiles: finished rolling files. state=${JSON.stringify(this.state)}`),this._renewWriteStream(),await new Promise(((e,t)=>{this.currentFileStream.write("","utf8",(()=>{this._clean().then(e).catch(t)}))}))}async _getExistingFiles(){const e=await _c.readdir(this.fileObject.dir).catch((()=>[]));bc(`_getExistingFiles: files=${e}`);const t=e.map((e=>this.fileNameParser(e))).filter((e=>e)),n=e=>(e.timestamp?e.timestamp:kc().getTime())-e.index;return t.sort(((e,t)=>n(e)-n(t))),t}_renewWriteStream(){const e=this.fileFormatter({date:this.state.currentDate,index:0}),t=e=>{try{return _c.mkdirSync(e,{recursive:!0})}catch(n){if("ENOENT"===n.code)return t(Bc.dirname(e)),t(e);if("EEXIST"!==n.code&&"EROFS"!==n.code)throw n;try{if(_c.statSync(e).isDirectory())return e;throw n}catch(e){throw n}}};t(this.fileObject.dir);const n={flags:this.options.flags,encoding:this.options.encoding,mode:this.options.mode};var r,u;_c.appendFileSync(e,"",(r={...n},u="flags",r["flag"]=r[u],delete r[u],r)),this.currentFileStream=_c.createWriteStream(e,n),this.currentFileStream.on("error",(e=>{this.emit("error",e)}))}async _clean(){const e=await this._getExistingFiles();if(bc(`_clean: numToKeep = ${this.options.numToKeep}, existingFiles = ${e.length}`),bc("_clean: existing files are: ",e),this._tooManyFiles(e.length)){const n=e.slice(0,e.length-this.options.numToKeep).map((e=>Bc.format({dir:this.fileObject.dir,base:e.filename})));await(t=n,bc(`deleteFiles: files to delete: ${t}`),Promise.all(t.map((e=>_c.unlink(e).catch((t=>{bc(`deleteFiles: error when unlinking ${e}, ignoring. Error was ${t}`)}))))))}var t}_tooManyFiles(e){return this.options.numToKeep>0&&e>this.options.numToKeep}};const Lc=Mc;var jc=class extends Lc{constructor(e,t,n,r){r||(r={}),t&&(r.maxSize=t),r.numBackups||0===r.numBackups||(n||0===n||(n=1),r.numBackups=n),super(e,r),this.backups=r.numBackups,this.size=this.options.maxSize}get theStream(){return this.currentFileStream}};const $c=Mc;var Hc={RollingFileWriteStream:Mc,RollingFileStream:jc,DateRollingFileStream:class extends $c{constructor(e,t,n){t&&"object"==typeof t&&(n=t,t=null),n||(n={}),t||(t="yyyy-MM-dd"),n.pattern=t,n.numBackups||0===n.numBackups?n.daysToKeep=n.numBackups:(n.daysToKeep||0===n.daysToKeep?process.emitWarning("options.daysToKeep is deprecated due to the confusion it causes when used together with file size rolling. Please use options.numBackups instead.","DeprecationWarning","streamroller-DEP0001"):n.daysToKeep=1,n.numBackups=n.daysToKeep),super(e,n),this.mode=this.options.mode}get theStream(){return this.currentFileStream}}};const Jc=Nr.exports("log4js:file"),Gc=p.default,Vc=Hc,Uc=E.default.EOL;let Wc=!1;const zc=new Set;function Kc(){zc.forEach((e=>{e.sighupHandler()}))}function qc(e,t,n,r){const u=new Vc.RollingFileStream(e,t,n,r);return u.on("error",(t=>{console.error("log4js.fileAppender - Writing to file %s, error happened ",e,t)})),u.on("drain",(()=>{process.emit("log4js:pause",!1)})),u}Eo.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.mode=e.mode||384,function(e,t,n,r,u,o){e=Gc.normalize(e),Jc("Creating file appender (",e,", ",n,", ",r=r||0===r?r:5,", ",u,", ",o,")");let i=qc(e,n,r,u);const s=function(e){if(i.writable){if(!0===u.removeColor){const t=/\x1b[[0-9;]*m/g;e.data=e.data.map((e=>"string"==typeof e?e.replace(t,""):e))}i.write(t(e,o)+Uc,"utf8")||process.emit("log4js:pause",!0)}};return s.reopen=function(){i.end((()=>{i=qc(e,n,r,u)}))},s.sighupHandler=function(){Jc("SIGHUP handler called."),s.reopen()},s.shutdown=function(e){zc.delete(s),0===zc.size&&Wc&&(process.removeListener("SIGHUP",Kc),Wc=!1),i.end("","utf-8",e)},zc.add(s),Wc||(process.on("SIGHUP",Kc),Wc=!0),s}(e.filename,n,e.maxLogSize,e.backups,e,e.timezoneOffset)};var Yc={};const Xc=Hc,Zc=E.default.EOL;function Qc(e,t,n,r,u){r.maxSize=r.maxLogSize;const o=function(e,t,n){const r=new Xc.DateRollingFileStream(e,t,n);return r.on("error",(t=>{console.error("log4js.dateFileAppender - Writing to file %s, error happened ",e,t)})),r.on("drain",(()=>{process.emit("log4js:pause",!1)})),r}(e,t,r),i=function(e){o.writable&&(o.write(n(e,u)+Zc,"utf8")||process.emit("log4js:pause",!0))};return i.shutdown=function(e){o.end("","utf-8",e)},i}Yc.configure=function(e,t){let n=t.basicLayout;return e.layout&&(n=t.layout(e.layout.type,e.layout)),e.alwaysIncludePattern||(e.alwaysIncludePattern=!1),e.mode=e.mode||384,Qc(e.filename,e.pattern,n,e,e.timezoneOffset)};var ea={};const ta=Nr.exports("log4js:fileSync"),na=p.default,ra=D.default,ua=E.default.EOL||"\n";function oa(e,t){if(ra.existsSync(e))return;const n=ra.openSync(e,t.flags,t.mode);ra.closeSync(n)}class ia{constructor(e,t,n,r){ta("In RollingFileStream"),function(){if(!e||!t||t<=0)throw new Error("You must specify a filename and file size")}(),this.filename=e,this.size=t,this.backups=n,this.options=r,this.currentSize=0,this.currentSize=function(e){let t=0;try{t=ra.statSync(e).size}catch(t){oa(e,r)}return t}(this.filename)}shouldRoll(){return ta("should roll with current size %d, and max size %d",this.currentSize,this.size),this.currentSize>=this.size}roll(e){const t=this,n=new RegExp(`^${na.basename(e)}`);function r(e){return n.test(e)}function u(t){return parseInt(t.substring(`${na.basename(e)}.`.length),10)||0}function o(e,t){return u(e)>u(t)?1:u(e) ${e}.${r+1}`),ra.renameSync(na.join(na.dirname(e),n),`${e}.${r+1}`)}}ta("Rolling, rolling, rolling"),ta("Renaming the old files"),ra.readdirSync(na.dirname(e)).filter(r).sort(o).reverse().forEach(i)}write(e,t){const n=this;ta("in write"),this.shouldRoll()&&(this.currentSize=0,this.roll(this.filename)),ta("writing the chunk to the file"),n.currentSize+=e.length,ra.appendFileSync(n.filename,e)}}ea.configure=function(e,t){let n=t.basicLayout;e.layout&&(n=t.layout(e.layout.type,e.layout));const r={flags:e.flags||"a",encoding:e.encoding||"utf8",mode:e.mode||384};return function(e,t,n,r,u,o){ta("fileSync appender created");const i=function(e,t,n){let r;var u;return t?r=new ia(e,t,n,o):(oa(u=e,o),r={write(e){ra.appendFileSync(u,e)}}),r}(e=na.normalize(e),n,r=r||0===r?r:5);return e=>{i.write(t(e,u)+ua)}}(e.filename,n,e.maxLogSize,e.backups,e.timezoneOffset,r)};var sa={};const ca=Nr.exports("log4js:tcp"),aa=S.default;sa.configure=function(e,t){ca(`configure with config = ${e}`);let n=function(e){return e.serialise()};return e.layout&&(n=t.layout(e.layout.type,e.layout)),function(e,t){let n=!1;const r=[];let u,o=3,i="__LOG4JS__";function s(e){ca("Writing log event to socket"),n=u.write(`${t(e)}${i}`,"utf8")}function c(){let e;for(ca("emptying buffer");e=r.shift();)s(e)}function a(e){n?s(e):(ca("buffering log event because it cannot write at the moment"),r.push(e))}return function t(){ca(`appender creating socket to ${e.host||"localhost"}:${e.port||5e3}`),i=`${e.endMsg||"__LOG4JS__"}`,u=aa.createConnection(e.port||5e3,e.host||"localhost"),u.on("connect",(()=>{ca("socket connected"),c(),n=!0})),u.on("drain",(()=>{ca("drain event received, emptying buffer"),n=!0,c()})),u.on("timeout",u.end.bind(u)),u.on("error",(e=>{ca("connection error",e),n=!1,c()})),u.on("close",t)}(),a.shutdown=function(e){ca("shutdown called"),r.length&&o?(ca("buffer has items, waiting 100ms to empty"),o-=1,setTimeout((()=>{a.shutdown(e)}),100)):(u.removeAllListeners("close"),u.end(e))},a}(e,n)};const la=p.default,fa=Nr.exports("log4js:appenders"),da=tu,Da=eo,pa=gu,Ea=hu,ma=to,ha=new Map;ha.set("console",oo),ha.set("stdout",so),ha.set("stderr",co),ha.set("logLevelFilter",ao),ha.set("categoryFilter",lo),ha.set("noLogFilter",Do),ha.set("file",Eo),ha.set("dateFile",Yc),ha.set("fileSync",ea),ha.set("tcp",sa);const ya=new Map,Ca=(e,t)=>{fa("Loading module from ",e);try{return require(e)}catch(n){return void da.throwExceptionIf(t,"MODULE_NOT_FOUND"!==n.code,`appender "${e}" could not be loaded (error was: ${n})`)}},Fa=new Set,ga=(e,t)=>{if(ya.has(e))return ya.get(e);if(!t.appenders[e])return!1;if(Fa.has(e))throw new Error(`Dependency loop detected for appender ${e}.`);Fa.add(e),fa(`Creating appender ${e}`);const n=Aa(e,t);return Fa.delete(e),ya.set(e,n),n},Aa=(e,t)=>{const n=t.appenders[e],r=n.type.configure?n.type:((e,t)=>ha.get(e)||Ca(`./${e}`,t)||Ca(e,t)||require.main&&Ca(la.join(la.dirname(require.main.filename),e),t)||Ca(la.join(process.cwd(),e),t))(n.type,t);return da.throwExceptionIf(t,da.not(r),`appender "${e}" is not valid (type "${n.type}" could not be found)`),r.appender&&fa(`DEPRECATION: Appender ${n.type} exports an appender function.`),r.shutdown&&fa(`DEPRECATION: Appender ${n.type} exports a shutdown function.`),fa(`${e}: clustering.isMaster ? ${Da.isMaster()}`),fa(`${e}: appenderModule is ${F.default.inspect(r)}`),Da.onlyOnMaster((()=>(fa(`calling appenderModule.configure for ${e} / ${n.type}`),r.configure(ma.modifyConfig(n),Ea,(e=>ga(e,t)),pa))),(()=>{}))},va=e=>{ya.clear(),Fa.clear();const t=[];Object.values(e.categories).forEach((e=>{t.push(...e.appenders)})),Object.keys(e.appenders).forEach((n=>{(t.includes(n)||"tcp-server"===e.appenders[n].type)&&ga(n,e)}))},Sa=()=>{va({appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"trace"}}})};Sa(),da.addListener((e=>{da.throwExceptionIf(e,da.not(da.anObject(e.appenders)),'must have a property "appenders" of type object.');const t=Object.keys(e.appenders);da.throwExceptionIf(e,da.not(t.length),"must define at least one appender."),t.forEach((t=>{da.throwExceptionIf(e,da.not(e.appenders[t].type),`appender "${t}" is not valid (must be an object with property "type")`)}))})),da.addListener(va),Au.exports=ya,Au.exports.init=Sa;var wa={exports:{}};!function(e){const t=Nr.exports("log4js:categories"),n=tu,r=gu,u=Au.exports,o=new Map;function i(e,t,n){if(!1===t.inherit)return;const r=n.lastIndexOf(".");if(r<0)return;const u=n.substring(0,r);let o=e.categories[u];o||(o={inherit:!0,appenders:[]}),i(e,o,u),!e.categories[u]&&o.appenders&&o.appenders.length&&o.level&&(e.categories[u]=o),t.appenders=t.appenders||[],t.level=t.level||o.level,o.appenders.forEach((e=>{t.appenders.includes(e)||t.appenders.push(e)})),t.parent=o}function s(e){if(!e.categories)return;Object.keys(e.categories).forEach((t=>{const n=e.categories[t];i(e,n,t)}))}n.addPreProcessingListener((e=>s(e))),n.addListener((e=>{n.throwExceptionIf(e,n.not(n.anObject(e.categories)),'must have a property "categories" of type object.');const t=Object.keys(e.categories);n.throwExceptionIf(e,n.not(t.length),"must define at least one category."),t.forEach((t=>{const o=e.categories[t];n.throwExceptionIf(e,[n.not(o.appenders),n.not(o.level)],`category "${t}" is not valid (must be an object with properties "appenders" and "level")`),n.throwExceptionIf(e,n.not(Array.isArray(o.appenders)),`category "${t}" is not valid (appenders must be an array of appender names)`),n.throwExceptionIf(e,n.not(o.appenders.length),`category "${t}" is not valid (appenders must contain at least one appender name)`),Object.prototype.hasOwnProperty.call(o,"enableCallStack")&&n.throwExceptionIf(e,"boolean"!=typeof o.enableCallStack,`category "${t}" is not valid (enableCallStack must be boolean type)`),o.appenders.forEach((r=>{n.throwExceptionIf(e,n.not(u.get(r)),`category "${t}" is not valid (appender "${r}" is not defined)`)})),n.throwExceptionIf(e,n.not(r.getLevel(o.level)),`category "${t}" is not valid (level "${o.level}" not recognised; valid levels are ${r.levels.join(", ")})`)})),n.throwExceptionIf(e,n.not(e.categories.default),'must define a "default" category.')}));const c=e=>{o.clear();Object.keys(e.categories).forEach((n=>{const i=e.categories[n],s=[];i.appenders.forEach((e=>{s.push(u.get(e)),t(`Creating category ${n}`),o.set(n,{appenders:s,level:r.getLevel(i.level),enableCallStack:i.enableCallStack||!1})}))}))},a=()=>{c({categories:{default:{appenders:["out"],level:"OFF"}}})};a(),n.addListener(c);const l=e=>(t(`configForCategory: searching for config for ${e}`),o.has(e)?(t(`configForCategory: ${e} exists in config, returning it`),o.get(e)):e.indexOf(".")>0?(t(`configForCategory: ${e} has hierarchy, searching for parents`),l(e.substring(0,e.lastIndexOf(".")))):(t("configForCategory: returning config for default category"),l("default")));e.exports=o,e.exports=Object.assign(e.exports,{appendersForCategory:e=>l(e).appenders,getLevelForCategory:e=>l(e).level,setLevelForCategory:(e,n)=>{let r=o.get(e);if(t(`setLevelForCategory: found ${r} for ${e}`),!r){const n=l(e);t(`setLevelForCategory: no config found for category, found ${n} for parents of ${e}`),r={appenders:n.appenders}}r.level=n,o.set(e,r)},getEnableCallStackForCategory:e=>!0===l(e).enableCallStack,setEnableCallStackForCategory:(e,t)=>{l(e).enableCallStack=t},init:a})}(wa);const Oa=Nr.exports("log4js:logger"),ba=Hu,_a=gu,Ba=eo,Pa=wa.exports,ka=tu,xa=/at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;function Na(e,t=4){const n=e.stack.split("\n").slice(t),r=xa.exec(n[0]);return r&&6===r.length?{functionName:r[1],fileName:r[2],lineNumber:parseInt(r[3],10),columnNumber:parseInt(r[4],10),callStack:n.join("\n")}:null}class Ia{constructor(e){if(!e)throw new Error("No category provided.");this.category=e,this.context={},this.parseCallStack=Na,Oa(`Logger created (${this.category}, ${this.level})`)}get level(){return _a.getLevel(Pa.getLevelForCategory(this.category),_a.TRACE)}set level(e){Pa.setLevelForCategory(this.category,_a.getLevel(e,this.level))}get useCallStack(){return Pa.getEnableCallStackForCategory(this.category)}set useCallStack(e){Pa.setEnableCallStackForCategory(this.category,!0===e)}log(e,...t){let n=_a.getLevel(e);n||(this._log(_a.WARN,"log4js:logger.log: invalid value for log-level as first parameter given: ",e),n=_a.INFO),this.isLevelEnabled(n)&&this._log(n,t)}isLevelEnabled(e){return this.level.isLessThanOrEqualTo(e)}_log(e,t){Oa(`sending log data (${e}) to appenders`);const n=new ba(this.category,e,t,this.context,this.useCallStack&&this.parseCallStack(new Error));Ba.send(n)}addContext(e,t){this.context[e]=t}removeContext(e){delete this.context[e]}clearContext(){this.context={}}setParseCallStackFunction(e){this.parseCallStack=e}}function Ta(e){const t=_a.getLevel(e),n=t.toString().toLowerCase().replace(/_([a-z])/g,(e=>e[1].toUpperCase())),r=n[0].toUpperCase()+n.slice(1);Ia.prototype[`is${r}Enabled`]=function(){return this.isLevelEnabled(t)},Ia.prototype[n]=function(...e){this.log(t,...e)}}_a.levels.forEach(Ta),ka.addListener((()=>{_a.levels.forEach(Ta)}));var Ra=Ia;const Ma=gu;function La(e){return e.originalUrl||e.url}function ja(e,t){for(let n=0;ne.source?e.source:e));t=new RegExp(n.join("|"))}return t}(t.nolog);return(e,i,s)=>{if(e._logging)return s();if(o&&o.test(e.originalUrl))return s();if(n.isLevelEnabled(r)||"auto"===t.level){const o=new Date,{writeHead:s}=i;e._logging=!0,i.writeHead=(e,t)=>{i.writeHead=s,i.writeHead(e,t),i.__statusCode=e,i.__headers=t||{}},i.on("finish",(()=>{i.responseTime=new Date-o,i.statusCode&&"auto"===t.level&&(r=Ma.INFO,i.statusCode>=300&&(r=Ma.WARN),i.statusCode>=400&&(r=Ma.ERROR)),r=function(e,t,n){let r=t;if(n){const t=n.find((t=>{let n=!1;return n=t.from&&t.to?e>=t.from&&e<=t.to:-1!==t.codes.indexOf(e),n}));t&&(r=Ma.getLevel(t.level,r))}return r}(i.statusCode,r,t.statusRules);const s=function(e,t,n){const r=[];return r.push({token:":url",replacement:La(e)}),r.push({token:":protocol",replacement:e.protocol}),r.push({token:":hostname",replacement:e.hostname}),r.push({token:":method",replacement:e.method}),r.push({token:":status",replacement:t.__statusCode||t.statusCode}),r.push({token:":response-time",replacement:t.responseTime}),r.push({token:":date",replacement:(new Date).toUTCString()}),r.push({token:":referrer",replacement:e.headers.referer||e.headers.referrer||""}),r.push({token:":http-version",replacement:`${e.httpVersionMajor}.${e.httpVersionMinor}`}),r.push({token:":remote-addr",replacement:e.headers["x-forwarded-for"]||e.ip||e._remoteAddress||e.socket&&(e.socket.remoteAddress||e.socket.socket&&e.socket.socket.remoteAddress)}),r.push({token:":user-agent",replacement:e.headers["user-agent"]}),r.push({token:":content-length",replacement:t.getHeader("content-length")||t.__headers&&t.__headers["Content-Length"]||"-"}),r.push({token:/:req\[([^\]]+)]/g,replacement:(t,n)=>e.headers[n.toLowerCase()]}),r.push({token:/:res\[([^\]]+)]/g,replacement:(e,n)=>t.getHeader(n.toLowerCase())||t.__headers&&t.__headers[n]}),(e=>{const t=e.concat();for(let e=0;eja(e,s)));t&&n.log(r,t)}else n.log(r,ja(u,s));t.context&&n.removeContext("res")}))}return s()}},nl=Va;let rl=!1;function ul(e){if(!rl)return;Ua("Received log event ",e);Za.appendersForCategory(e.categoryName).forEach((t=>{t(e)}))}function ol(e){rl&&il();let t=e;return"string"==typeof t&&(t=function(e){Ua(`Loading configuration from ${e}`);try{return JSON.parse(Wa.readFileSync(e,"utf8"))}catch(t){throw new Error(`Problem reading config from file "${e}". Error was ${t.message}`,t)}}(e)),Ua(`Configuration is ${t}`),Ka.configure(za(t)),el.onMessage(ul),rl=!0,sl}function il(e){Ua("Shutdown called. Disabling all log writing."),rl=!1;const t=Array.from(Xa.values());Xa.init(),Za.init();const n=t.reduceRight(((e,t)=>t.shutdown?e+1:e),0);if(0===n)return Ua("No appenders with shutdown functions found."),void 0!==e&&e();let r,u=0;function o(t){r=r||t,u+=1,Ua(`Appender shutdowns complete: ${u} / ${n}`),u>=n&&(Ua("All shutdown functions completed."),e&&e(r))}return Ua(`Found ${n} appenders with shutdown functions.`),t.filter((e=>e.shutdown)).forEach((e=>e.shutdown(o))),null}const sl={getLogger:function(e){return rl||ol(process.env.LOG4JS_CONFIG||{appenders:{out:{type:"stdout"}},categories:{default:{appenders:["out"],level:"OFF"}}}),new Qa(e||"default")},configure:ol,shutdown:il,connectLogger:tl,levels:Ya,addLayout:qa.addLayout,recording:function(){return nl}};var cl=sl,al={};Object.defineProperty(al,"__esModule",{value:!0}),al.levelMap=al.getLevel=al.setCategoriesLevel=al.getConfiguration=al.setConfiguration=void 0;const ll=cl;let fl={appenders:{debug:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %p %c %[%m%]"}},info:{type:"stdout",layout:{type:"pattern",pattern:"[%d] > hvigor %[%m%]"}},"no-pattern-info":{type:"stdout",layout:{type:"pattern",pattern:"%m"}},wrong:{type:"stderr",layout:{type:"pattern",pattern:"[%d] > hvigor %[%p: %m%]"}},"just-debug":{type:"logLevelFilter",appender:"debug",level:"debug",maxLevel:"debug"},"just-info":{type:"logLevelFilter",appender:"info",level:"info",maxLevel:"info"},"just-wrong":{type:"logLevelFilter",appender:"wrong",level:"warn",maxLevel:"error"}},categories:{default:{appenders:["just-debug","just-info","just-wrong"],level:"debug"},"no-pattern-info":{appenders:["no-pattern-info"],level:"info"}}};al.setConfiguration=e=>{fl=e};al.getConfiguration=()=>fl;let dl=ll.levels.DEBUG;al.setCategoriesLevel=(e,t)=>{dl=e;const n=fl.categories;for(const r in n)(null==t?void 0:t.includes(r))||Object.prototype.hasOwnProperty.call(n,r)&&(n[r].level=e.levelStr)};al.getLevel=()=>dl,al.levelMap=new Map([["ALL",ll.levels.ALL],["MARK",ll.levels.MARK],["TRACE",ll.levels.TRACE],["DEBUG",ll.levels.DEBUG],["INFO",ll.levels.INFO],["WARN",ll.levels.WARN],["ERROR",ll.levels.ERROR],["FATAL",ll.levels.FATAL],["OFF",ll.levels.OFF]]);var Dl=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),pl=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),El=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Dl(t,e,n);return pl(t,e),t};Object.defineProperty(xr,"__esModule",{value:!0}),xr.evaluateLogLevel=xr.HvigorLogger=void 0;const ml=El(cl),hl=cl,yl=El(F.default),Cl=al;class Fl{constructor(e){ml.configure((0,Cl.getConfiguration)()),this._logger=ml.getLogger(e),this._logger.level=(0,Cl.getLevel)()}static getLogger(e){return new Fl(e)}log(e,...t){this._logger.log(e,...t)}debug(e,...t){this._logger.debug(e,...t)}info(e,...t){this._logger.info(e,...t)}warn(e,...t){void 0!==e&&""!==e&&this._logger.warn(e,...t)}error(e,...t){this._logger.error(e,...t)}_printTaskExecuteInfo(e,t){this.info(`Finished :${e}... after ${t}`)}_printFailedTaskInfo(e){this.error(`Failed :${e}... `)}_printDisabledTaskInfo(e){this.info(`Disabled :${e}... `)}_printUpToDateTaskInfo(e){this.info(`UP-TO-DATE :${e}... `)}errorMessageExit(e,...t){throw new Error(yl.format(e,...t))}errorExit(e,t,...n){t&&this._logger.error(t,n),this._logger.error(e.stack)}setLevel(e,t){(0,Cl.setCategoriesLevel)(e,t),ml.shutdown(),ml.configure((0,Cl.getConfiguration)())}getLevel(){return this._logger.level}configure(e){const t=(0,Cl.getConfiguration)(),n={appenders:{...t.appenders,...e.appenders},categories:{...t.categories,...e.categories}};(0,Cl.setConfiguration)(n),ml.shutdown(),ml.configure(n)}}xr.HvigorLogger=Fl,xr.evaluateLogLevel=function(e,t){t.debug?e.setLevel(hl.levels.DEBUG):t.warn?e.setLevel(hl.levels.WARN):t.error?e.setLevel(hl.levels.ERROR):e.setLevel(hl.levels.INFO)};var gl=w&&w.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(X,"__esModule",{value:!0}),X.parseJsonText=X.parseJsonFile=void 0;const Al=Z,vl=gl(kr),Sl=gl(p.default),wl=gl(E.default),Ol=xr.HvigorLogger.getLogger("parse-json-util");var bl;!function(e){e[e.Char=0]="Char",e[e.EOF=1]="EOF",e[e.Identifier=2]="Identifier"}(bl||(bl={}));let _l,Bl,Pl,kl,xl,Nl,Il="start",Tl=[],Rl=0,Ml=1,Ll=0,jl=!1,$l="default",Hl="'",Jl=1;function Gl(e,t=!1){Bl=String(e),Il="start",Tl=[],Rl=0,Ml=1,Ll=0,kl=void 0,jl=t;do{_l=Vl(),Xl[Il]()}while("eof"!==_l.type);return kl}function Vl(){for($l="default",xl="",Hl="'",Jl=1;;){Nl=Ul();const e=zl[$l]();if(e)return e}}function Ul(){if(Bl[Rl])return String.fromCodePoint(Bl.codePointAt(Rl))}function Wl(){const e=Ul();return"\n"===e?(Ml++,Ll=0):e?Ll+=e.length:Ll++,e&&(Rl+=e.length),e}X.parseJsonFile=function(e,t=!1,n="utf-8"){const r=vl.default.readFileSync(Sl.default.resolve(e),{encoding:n});try{return Gl(r,t)}catch(t){if(t instanceof SyntaxError){const n=t.message.split("at");2===n.length&&Ol.errorMessageExit(`${n[0].trim()}${wl.default.EOL}\t at ${e}:${n[1].trim()}`)}Ol.errorMessageExit(`${e} is not in valid JSON/JSON5 format.`)}},X.parseJsonText=Gl;const zl={default(){switch(Nl){case"/":return Wl(),void($l="comment");case void 0:return Wl(),Kl("eof")}if(!Al.JudgeUtil.isIgnoreChar(Nl)&&!Al.JudgeUtil.isSpaceSeparator(Nl))return zl[Il]();Wl()},start(){$l="value"},beforePropertyName(){switch(Nl){case"$":case"_":return xl=Wl(),void($l="identifierName");case"\\":return Wl(),void($l="identifierNameStartEscape");case"}":return Kl("punctuator",Wl());case'"':case"'":return Hl=Nl,Wl(),void($l="string")}if(Al.JudgeUtil.isIdStartChar(Nl))return xl+=Wl(),void($l="identifierName");throw tf(bl.Char,Wl())},afterPropertyName(){if(":"===Nl)return Kl("punctuator",Wl());throw tf(bl.Char,Wl())},beforePropertyValue(){$l="value"},afterPropertyValue(){switch(Nl){case",":case"}":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},beforeArrayValue(){if("]"===Nl)return Kl("punctuator",Wl());$l="value"},afterArrayValue(){switch(Nl){case",":case"]":return Kl("punctuator",Wl())}throw tf(bl.Char,Wl())},end(){throw tf(bl.Char,Wl())},comment(){switch(Nl){case"*":return Wl(),void($l="multiLineComment");case"/":return Wl(),void($l="singleLineComment")}throw tf(bl.Char,Wl())},multiLineComment(){switch(Nl){case"*":return Wl(),void($l="multiLineCommentAsterisk");case void 0:throw tf(bl.Char,Wl())}Wl()},multiLineCommentAsterisk(){switch(Nl){case"*":return void Wl();case"/":return Wl(),void($l="default");case void 0:throw tf(bl.Char,Wl())}Wl(),$l="multiLineComment"},singleLineComment(){switch(Nl){case"\n":case"\r":case"\u2028":case"\u2029":return Wl(),void($l="default");case void 0:return Wl(),Kl("eof")}Wl()},value(){switch(Nl){case"{":case"[":return Kl("punctuator",Wl());case"n":return Wl(),ql("ull"),Kl("null",null);case"t":return Wl(),ql("rue"),Kl("boolean",!0);case"f":return Wl(),ql("alse"),Kl("boolean",!1);case"-":case"+":return"-"===Wl()&&(Jl=-1),void($l="numerical");case".":case"0":case"I":case"N":return void($l="numerical");case'"':case"'":return Hl=Nl,Wl(),xl="",void($l="string")}if(void 0===Nl||!Al.JudgeUtil.isDigitWithoutZero(Nl))throw tf(bl.Char,Wl());$l="numerical"},numerical(){switch(Nl){case".":return xl=Wl(),void($l="decimalPointLeading");case"0":return xl=Wl(),void($l="zero");case"I":return Wl(),ql("nfinity"),Kl("numeric",Jl*(1/0));case"N":return Wl(),ql("aN"),Kl("numeric",NaN)}if(void 0!==Nl&&Al.JudgeUtil.isDigitWithoutZero(Nl))return xl=Wl(),void($l="decimalInteger");throw tf(bl.Char,Wl())},zero(){switch(Nl){case".":case"e":case"E":return void($l="decimal");case"x":case"X":return xl+=Wl(),void($l="hexadecimal")}return Kl("numeric",0)},decimalInteger(){switch(Nl){case".":case"e":case"E":return void($l="decimal")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimal(){switch(Nl){case".":xl+=Wl(),$l="decimalFraction";break;case"e":case"E":xl+=Wl(),$l="decimalExponent"}},decimalPointLeading(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalFraction");throw tf(bl.Char,Wl())},decimalFraction(){switch(Nl){case"e":case"E":return xl+=Wl(),void($l="decimalExponent")}if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},decimalExponent(){switch(Nl){case"+":case"-":return xl+=Wl(),void($l="decimalExponentSign")}if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentSign(){if(Al.JudgeUtil.isDigit(Nl))return xl+=Wl(),void($l="decimalExponentInteger");throw tf(bl.Char,Wl())},decimalExponentInteger(){if(!Al.JudgeUtil.isDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},hexadecimal(){if(Al.JudgeUtil.isHexDigit(Nl))return xl+=Wl(),void($l="hexadecimalInteger");throw tf(bl.Char,Wl())},hexadecimalInteger(){if(!Al.JudgeUtil.isHexDigit(Nl))return Kl("numeric",Jl*Number(xl));xl+=Wl()},identifierNameStartEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":break;default:if(!Al.JudgeUtil.isIdStartChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},identifierName(){switch(Nl){case"$":case"_":case"‌":case"‍":return void(xl+=Wl());case"\\":return Wl(),void($l="identifierNameEscape")}if(!Al.JudgeUtil.isIdContinueChar(Nl))return Kl("identifier",xl);xl+=Wl()},identifierNameEscape(){if("u"!==Nl)throw tf(bl.Char,Wl());Wl();const e=Yl();switch(e){case"$":case"_":case"‌":case"‍":break;default:if(!Al.JudgeUtil.isIdContinueChar(e))throw tf(bl.Identifier)}xl+=e,$l="identifierName"},string(){switch(Nl){case"\\":return Wl(),void(xl+=function(){const e=Ul(),t=function(){switch(Ul()){case"b":return Wl(),"\b";case"f":return Wl(),"\f";case"n":return Wl(),"\n";case"r":return Wl(),"\r";case"t":return Wl(),"\t";case"v":return Wl(),"\v"}return}();if(t)return t;switch(e){case"0":if(Wl(),Al.JudgeUtil.isDigit(Ul()))throw tf(bl.Char,Wl());return"\0";case"x":return Wl(),function(){let e="",t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());if(e+=Wl(),t=Ul(),!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());return e+=Wl(),String.fromCodePoint(parseInt(e,16))}();case"u":return Wl(),Yl();case"\n":case"\u2028":case"\u2029":return Wl(),"";case"\r":return Wl(),"\n"===Ul()&&Wl(),""}if(void 0===e||Al.JudgeUtil.isDigitWithoutZero(e))throw tf(bl.Char,Wl());return Wl()}());case'"':case"'":if(Nl===Hl){const e=Kl("string",xl);return Wl(),e}return void(xl+=Wl());case"\n":case"\r":case void 0:throw tf(bl.Char,Wl());case"\u2028":case"\u2029":!function(e){Ol.warn(`JSON5: '${ef(e)}' in strings is not valid ECMAScript; consider escaping.`)}(Nl)}xl+=Wl()}};function Kl(e,t){return{type:e,value:t,line:Ml,column:Ll}}function ql(e){for(const t of e){if(Ul()!==t)throw tf(bl.Char,Wl());Wl()}}function Yl(){let e="",t=4;for(;t-- >0;){const t=Ul();if(!Al.JudgeUtil.isHexDigit(t))throw tf(bl.Char,Wl());e+=Wl()}return String.fromCodePoint(parseInt(e,16))}const Xl={start(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},beforePropertyName(){switch(_l.type){case"identifier":case"string":return Pl=_l.value,void(Il="afterPropertyName");case"punctuator":return void Ql();case"eof":throw tf(bl.EOF)}},afterPropertyName(){if("eof"===_l.type)throw tf(bl.EOF);Il="beforePropertyValue"},beforePropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);Zl()},afterPropertyValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforePropertyName");case"}":Ql()}},beforeArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);"punctuator"!==_l.type||"]"!==_l.value?Zl():Ql()},afterArrayValue(){if("eof"===_l.type)throw tf(bl.EOF);switch(_l.value){case",":return void(Il="beforeArrayValue");case"]":Ql()}},end(){}};function Zl(){const e=function(){let e;switch(_l.type){case"punctuator":switch(_l.value){case"{":e={};break;case"[":e=[]}break;case"null":case"boolean":case"numeric":case"string":e=_l.value}return e}();if(jl&&"object"==typeof e&&(e._line=Ml,e._column=Ll),void 0===kl)kl=e;else{const t=Tl[Tl.length-1];Array.isArray(t)?jl&&"object"!=typeof e?t.push({value:e,_line:Ml,_column:Ll}):t.push(e):t[Pl]=jl&&"object"!=typeof e?{value:e,_line:Ml,_column:Ll}:e}!function(e){if(e&&"object"==typeof e)Tl.push(e),Il=Array.isArray(e)?"beforeArrayValue":"beforePropertyName";else{const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}}(e)}function Ql(){Tl.pop();const e=Tl[Tl.length-1];Il=e?Array.isArray(e)?"afterArrayValue":"afterPropertyValue":"end"}function ef(e){const t={"'":"\\'",'"':'\\"',"\\":"\\\\","\b":"\\b","\f":"\\f","\n":"\\n","\r":"\\r","\t":"\\t","\v":"\\v","\0":"\\0","\u2028":"\\u2028","\u2029":"\\u2029"};if(t[e])return t[e];if(e<" "){const t=e.charCodeAt(0).toString(16);return`\\x${`00${t}`.substring(t.length)}`}return e}function tf(e,t){let n="";switch(e){case bl.Char:n=void 0===t?`JSON5: invalid end of input at ${Ml}:${Ll}`:`JSON5: invalid character '${ef(t)}' at ${Ml}:${Ll}`;break;case bl.EOF:n=`JSON5: invalid end of input at ${Ml}:${Ll}`;break;case bl.Identifier:Ll-=5,n=`JSON5: invalid identifier character at ${Ml}:${Ll}`}const r=new nf(n);return r.lineNumber=Ml,r.columnNumber=Ll,r}class nf extends SyntaxError{}var rf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),uf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&rf(t,e,n);return uf(t,e),t};Object.defineProperty(Y,"__esModule",{value:!0});var sf=Y.cleanWorkSpace=Ff=Y.executeInstallHvigor=yf=Y.isHvigorInstalled=mf=Y.isAllDependenciesInstalled=void 0;const cf=of(D.default),af=of(p.default),lf=b,ff=j,df=$,Df=X;let pf,Ef;var mf=Y.isAllDependenciesInstalled=function(){function e(e){const t=null==e?void 0:e.dependencies;return void 0===t?0:Object.getOwnPropertyNames(t).length}if(pf=gf(),Ef=Af(),e(pf)+1!==e(Ef))return!1;for(const e in null==pf?void 0:pf.dependencies)if(!(0,ff.hasNpmPackInPaths)(e,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])||!hf(e,pf,Ef))return!1;return!0};function hf(e,t,n){return void 0!==n.dependencies&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,t.dependencies[e])===n.dependencies[e]}var yf=Y.isHvigorInstalled=function(){return pf=gf(),Ef=Af(),(0,ff.hasNpmPackInPaths)(lf.HVIGOR_ENGINE_PACKAGE_NAME,[lf.HVIGOR_PROJECT_DEPENDENCIES_HOME])&&(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion)===Ef.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]};const Cf={cwd:lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,stdio:["inherit","inherit","inherit"]};var Ff=Y.executeInstallHvigor=function(){(0,df.logInfoPrintConsole)("Hvigor installing...");const e={dependencies:{}};e.dependencies[lf.HVIGOR_ENGINE_PACKAGE_NAME]=(0,ff.offlinePluginConversion)(lf.HVIGOR_PROJECT_ROOT_DIR,pf.hvigorVersion);try{cf.mkdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,{recursive:!0});const t=af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,lf.DEFAULT_PACKAGE_JSON);cf.writeFileSync(t,JSON.stringify(e))}catch(e){(0,df.logErrorAndExit)(e)}!function(){const e=["config","set","store-dir",lf.HVIGOR_PNPM_STORE_PATH];(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,e,Cf)}(),(0,ff.executeCommand)(lf.HVIGOR_WRAPPER_PNPM_SCRIPT_PATH,["install"],Cf)};function gf(){const e=af.resolve(lf.HVIGOR_PROJECT_WRAPPER_HOME,lf.DEFAULT_HVIGOR_CONFIG_JSON_FILE_NAME);return cf.existsSync(e)||(0,df.logErrorAndExit)(`Error: Hvigor config file ${e} does not exist.`),(0,Df.parseJsonFile)(e)}function Af(){return cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH)?(0,Df.parseJsonFile)(lf.HVIGOR_PROJECT_DEPENDENCY_PACKAGE_JSON_PATH):{dependencies:{}}}sf=Y.cleanWorkSpace=function(){if((0,df.logInfoPrintConsole)("Hvigor cleaning..."),!cf.existsSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME))return;const e=cf.readdirSync(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME);if(e&&0!==e.length){cf.existsSync(lf.HVIGOR_BOOT_JS_FILE_PATH)&&(0,ff.executeCommand)(process.argv[0],[lf.HVIGOR_BOOT_JS_FILE_PATH,"--stop-daemon"],{});try{e.forEach((e=>{cf.rmSync(af.resolve(lf.HVIGOR_PROJECT_DEPENDENCIES_HOME,e),{recursive:!0})}))}catch(e){(0,df.logErrorAndExit)(`The hvigor build tool cannot be installed. Please manually clear the workspace directory and synchronize the project again.\n\n Workspace Path: ${lf.HVIGOR_PROJECT_DEPENDENCIES_HOME}.`)}}};var vf={},Sf=w&&w.__createBinding||(Object.create?function(e,t,n,r){void 0===r&&(r=n);var u=Object.getOwnPropertyDescriptor(t,n);u&&!("get"in u?!t.__esModule:u.writable||u.configurable)||(u={enumerable:!0,get:function(){return t[n]}}),Object.defineProperty(e,r,u)}:function(e,t,n,r){void 0===r&&(r=n),e[r]=t[n]}),wf=w&&w.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),Of=w&&w.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var n in e)"default"!==n&&Object.prototype.hasOwnProperty.call(e,n)&&Sf(t,e,n);return wf(t,e),t};Object.defineProperty(vf,"__esModule",{value:!0});var bf=vf.executeBuild=void 0;const _f=b,Bf=Of(D.default),Pf=Of(p.default),kf=$;bf=vf.executeBuild=function(){const e=Pf.resolve(_f.HVIGOR_PROJECT_DEPENDENCIES_HOME,"node_modules","@ohos","hvigor","bin","hvigor.js");try{const t=Bf.realpathSync(e);require(t)}catch(t){(0,kf.logErrorAndExit)(`Error: ENOENT: no such file ${e},delete ${_f.HVIGOR_PROJECT_DEPENDENCIES_HOME} and retry.`)}},function(){if(O.checkNpmConifg(),O.environmentHandler(),O.isPnpmAvailable()||O.executeInstallPnpm(),yf()&&mf())bf();else{sf();try{Ff()}catch(e){return void sf()}bf()}}(); \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/hvigorfile.ts b/ohos/test_visibility_detector/ohos/hvigorfile.ts new file mode 100644 index 0000000000000000000000000000000000000000..5a172b770e3b15f67c12152d00f38f2084d3915b --- /dev/null +++ b/ohos/test_visibility_detector/ohos/hvigorfile.ts @@ -0,0 +1,17 @@ +/* +* Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +* See the License for the specific language governing permissions and +* limitations under the License. +*/ + +// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently. +export { appTasks } from '@ohos/hvigor-ohos-plugin'; \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/hvigorw b/ohos/test_visibility_detector/ohos/hvigorw new file mode 100644 index 0000000000000000000000000000000000000000..5efd8343d3232bdd1d9b7f67a3326034054c5396 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/hvigorw @@ -0,0 +1,61 @@ +#!/bin/bash + +# Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# ---------------------------------------------------------------------------- +# Hvigor startup script, version 1.0.0 +# +# Required ENV vars: +# ------------------ +# NODE_HOME - location of a Node home dir +# or +# Add /usr/local/nodejs/bin to the PATH environment variable +# ---------------------------------------------------------------------------- + +HVIGOR_APP_HOME=$(dirname $(readlink -f $0)) +HVIGOR_WRAPPER_SCRIPT=${HVIGOR_APP_HOME}/hvigor/hvigor-wrapper.js +warn() { + echo "" + echo -e "\033[1;33m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +error() { + echo "" + echo -e "\033[1;31m`date '+[%Y-%m-%d %H:%M:%S]'`$@\033[0m" +} + +fail() { + error "$@" + exit 1 +} + +# Determine node to start hvigor wrapper script +if [ -n "${NODE_HOME}" ];then + EXECUTABLE_NODE="${NODE_HOME}/bin/node" + if [ ! -x "$EXECUTABLE_NODE" ];then + fail "ERROR: NODE_HOME is set to an invalid directory,check $NODE_HOME\n\nPlease set NODE_HOME in your environment to the location where your nodejs installed" + fi +else + EXECUTABLE_NODE="node" + which ${EXECUTABLE_NODE} > /dev/null 2>&1 || fail "ERROR: NODE_HOME is not set and not 'node' command found in your path" +fi + +# Check hvigor wrapper script +if [ ! -r "$HVIGOR_WRAPPER_SCRIPT" ];then + fail "ERROR: Couldn't find hvigor/hvigor-wrapper.js in ${HVIGOR_APP_HOME}" +fi + +# start hvigor-wrapper script +exec "${EXECUTABLE_NODE}" \ + "${HVIGOR_WRAPPER_SCRIPT}" "$@" diff --git a/ohos/test_visibility_detector/ohos/hvigorw.bat b/ohos/test_visibility_detector/ohos/hvigorw.bat new file mode 100644 index 0000000000000000000000000000000000000000..6861293e47dfd0186da380321b73be9033507e24 --- /dev/null +++ b/ohos/test_visibility_detector/ohos/hvigorw.bat @@ -0,0 +1,64 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Hvigor startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +set WRAPPER_MODULE_PATH=%APP_HOME%\hvigor\hvigor-wrapper.js +set NODE_EXE=node.exe + +goto start + +:start +@rem Find node.exe +if defined NODE_HOME goto findNodeFromNodeHome + +%NODE_EXE% --version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto execute + +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:findNodeFromNodeHome +set NODE_HOME=%NODE_HOME:"=% +set NODE_EXE_PATH=%NODE_HOME%/%NODE_EXE% + +if exist "%NODE_EXE_PATH%" goto execute +echo. +echo ERROR: NODE_HOME is not set and no 'node' command could be found in your PATH. +echo. +echo Please set the NODE_HOME variable in your environment to match the +echo location of your NodeJs installation. + +goto fail + +:execute +@rem Execute hvigor +"%NODE_EXE%" %WRAPPER_MODULE_PATH% %* + +if "%ERRORLEVEL%" == "0" goto hvigorwEnd + +:fail +exit /b 1 + +:hvigorwEnd +if "%OS%" == "Windows_NT" endlocal + +:end diff --git a/ohos/test_visibility_detector/ohos/oh-package-lock.json5 b/ohos/test_visibility_detector/ohos/oh-package-lock.json5 new file mode 100644 index 0000000000000000000000000000000000000000..bc40219d5aa573d750a40c2948a91e8bc9a36abc --- /dev/null +++ b/ohos/test_visibility_detector/ohos/oh-package-lock.json5 @@ -0,0 +1,13 @@ +{ + "lockfileVersion": 1, + "ATTENTION": "THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.", + "specifiers": { + "@ohos/hypium@1.0.6": "@ohos/hypium@1.0.6" + }, + "packages": { + "@ohos/hypium@1.0.6": { + "resolved": "https://repo.harmonyos.com/ohpm/@ohos/hypium/-/hypium-1.0.6.tgz", + "integrity": "sha512-bb3DWeWhYrFqj9mPFV3yZQpkm36kbcK+YYaeY9g292QKSjOdmhEIQR2ULPvyMsgSR4usOBf5nnYrDmaCCXirgQ==" + } + } +} \ No newline at end of file diff --git a/ohos/test_visibility_detector/ohos/oh-package.json5 b/ohos/test_visibility_detector/ohos/oh-package.json5 new file mode 100644 index 0000000000000000000000000000000000000000..a1af1539da06972d6b27b4078c69e20f9328405e --- /dev/null +++ b/ohos/test_visibility_detector/ohos/oh-package.json5 @@ -0,0 +1,12 @@ +{ + "license": "", + "devDependencies": { + "@ohos/hypium": "1.0.6" + }, + "author": "", + "name": "apptemplate", + "description": "Please describe the basic information.", + "main": "", + "version": "1.0.0", + "dependencies": {} +} diff --git a/ohos/test_visibility_detector/pubspec.yaml b/ohos/test_visibility_detector/pubspec.yaml new file mode 100644 index 0000000000000000000000000000000000000000..72a53bf23937ba71695273f062df6b3a14aa58e4 --- /dev/null +++ b/ohos/test_visibility_detector/pubspec.yaml @@ -0,0 +1,28 @@ +## +## Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. +## Licensed under the Apache License, Version 2.0 (the "License"); +## you may not use this file except in compliance with the License. +## You may obtain a copy of the License at +## +## http://www.apache.org/licenses/LICENSE-2.0 +## +## Unless required by applicable law or agreed to in writing, software +## distributed under the License is distributed on an "AS IS" BASIS, +## WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +## See the License for the specific language governing permissions and +## limitations under the License. +## + +name: test_visibility_detector +description: A new Flutter project. +publish_to: 'none' +version: 1.0.0 + +environment: + sdk: '>=2.19.6 <3.0.0' +dependencies: + flutter: + sdk: flutter + visibility_detector: 0.4.0+2 +flutter: + uses-material-design: true \ No newline at end of file