update version
@@ -1,141 +1,35 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kawaii Flip Friends - Privacy Policy</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
line-height: 1.6;
|
||||
color: #333;
|
||||
max-width: 800px;
|
||||
margin: 0 auto;
|
||||
padding: 20px;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
h1 {
|
||||
color: #2c3e50;
|
||||
text-align: center;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
h2 {
|
||||
color: #34495e;
|
||||
margin-top: 25px;
|
||||
margin-bottom: 15px;
|
||||
border-bottom: 1px solid #e0e0e0;
|
||||
padding-bottom: 5px;
|
||||
}
|
||||
h3 {
|
||||
color: #4a69bd;
|
||||
margin-top: 20px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
p {
|
||||
margin-bottom: 15px;
|
||||
text-align: justify;
|
||||
}
|
||||
ul {
|
||||
margin-bottom: 15px;
|
||||
padding-left: 20px;
|
||||
}
|
||||
li {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
.contact-email {
|
||||
font-weight: bold;
|
||||
color: #e74c3c;
|
||||
}
|
||||
.footer {
|
||||
margin-top: 40px;
|
||||
padding-top: 20px;
|
||||
border-top: 1px solid #e0e0e0;
|
||||
font-size: 0.9em;
|
||||
color: #7f8c8d;
|
||||
}
|
||||
</style>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Kawaii Flip Friends Privacy Policy</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Kawaii Flip Friends User Privacy Policy</h1>
|
||||
<h1>Privacy Policy</h1>
|
||||
<p><strong>Effective Date:</strong> February 10, 2026</p>
|
||||
|
||||
<p>Welcome to Kawaii Flip Friends, a memory matching game developed by us (hereinafter referred to as "this Game"). We attach great importance to the privacy protection of users (hereinafter referred to as "you") and are committed to safeguarding the security and legitimate rights and interests of your personal information. This Privacy Policy is intended to clearly inform you of the methods, scope and purposes of collecting, using, storing and sharing your personal information, as well as the rights you enjoy, while specifying matters related to minor protection and reporting. This Policy applies to all users of this Game.</p>
|
||||
<p>This Privacy Policy applies to the mobile application Kawaii Flip Friends.</p>
|
||||
|
||||
<p>Please carefully read and fully understand all the terms of this Privacy Policy before using this Game. Once you download, install and use this Game, it shall be deemed that you have read, understood and agreed to all the agreements in this Policy. If you do not agree to this Policy, please do not use this Game.</p>
|
||||
<h2>1. Information We Collect</h2>
|
||||
<p>We automatically collect limited non-sensitive device and usage information, including device model, system version, network status, app usage records, and anonymous interaction data.</p>
|
||||
|
||||
<h2>I. Personal Information We Collect</h2>
|
||||
<h2>2. Use of Collected Information</h2>
|
||||
<p>Collected data is used to ensure stable operation, optimize user experience, deliver advertisements, analyze product performance, and improve services.</p>
|
||||
|
||||
<p>To ensure the normal operation of this Game, optimize the game experience, provide advertising services and conduct data statistics and analysis, we will collect relevant information generated during your use of this Game in accordance with the principles of "legality, propriety and necessity", as follows:</p>
|
||||
<h2>3. Third-Party Data Sharing</h2>
|
||||
<p>Anonymous device and usage data may be shared with trusted advertising partners. We do not sell personal data.</p>
|
||||
|
||||
<h3>1.1 Game Usage-Related Information</h3>
|
||||
<p>When you use this Game, we will automatically collect non-personally identifiable information related to game usage, including but not limited to: game login time, game duration, memory matching battle records, game level progress, in-game operation behaviors, device model, operating system version, unique device identifiers (such as IMEI, Android ID), network type, IP address, WLAN access point, etc. Such information is only used to analyze the game operation status, optimize game gameplay, and fix game bugs, and will not individually identify your personal identity.</p>
|
||||
<h2>4. Children's Privacy Statement</h2>
|
||||
<p>The App is not intended for children under 13. If personal information of a child is discovered, it will be removed promptly.</p>
|
||||
|
||||
<h3>1.2 Advertising-Related Information</h3>
|
||||
<p>This Game integrates advertising services. To provide you with personalized and compliant advertising displays, the advertising may collect your device information (such as device model, operating system, device identifier), network information, advertising display records, advertising click behaviors and other information. The collection and use of such information shall be implemented by the advertising service provider in accordance with its own privacy policy. We will not interfere with its information processing process, nor will we obtain your personally identifiable information from the advertising service.</p>
|
||||
<h2>5. Data Security Protection</h2>
|
||||
<p>Reasonable technical and operational security measures are implemented to protect user information.</p>
|
||||
|
||||
<h3>1.3 Data Reporting-Related Information</h3>
|
||||
<p>This Game uses service providers such as Adjust for data reporting to count operational data such as game installations, activity levels, and user retention rates, helping us optimize game operation strategies. The service provider may collect non-personally identifiable information such as your device identifier, IP address, network type, game installation and startup information. Its information processing is only used for game operational data statistics and does not involve the collection or disclosure of personally identifiable information.</p>
|
||||
<h2>6. Policy Updates</h2>
|
||||
<p>We may update this policy periodically. Continued use constitutes acceptance of updates.</p>
|
||||
|
||||
<h3>1.4 Voluntarily Provided Information</h3>
|
||||
<p>When you take the initiative to contact our customer service, participate in in-game activities or feedback issues, you may voluntarily provide your contact information (such as email address), problem description and other information. Such information is only used to respond to your needs and solve the problems you encounter, and will not be used for other irrelevant purposes.</p>
|
||||
|
||||
<h2>II. Use of Personal Information</h2>
|
||||
<p>The personal information we collect will be strictly used for the following purposes. Without your explicit consent, it will not be used beyond the following scope:</p>
|
||||
<ul>
|
||||
<li>Ensure the normal operation of this Game, fix game bugs, handle game failures, and ensure that you can normally experience core game functions such as memory matching;</li>
|
||||
<li>Optimize the game experience, adjust game difficulty and optimize gameplay design according to your in-game operation behaviors, level progress and other information to provide you with game content more suitable for your needs;</li>
|
||||
<li>Provide advertising services, display ads that match your interests to improve advertising display effect, and support the free operation of the Game;</li>
|
||||
<li>Conduct data statistics and analysis, use the reported operational data to understand the game user activity, retention rate and other situations, optimize game operation strategies, and improve game quality;</li>
|
||||
<li>Respond to your inquiries, complaints and reports, handle the problems you feedback, and protect your legitimate rights and interests;</li>
|
||||
<li>Comply with relevant laws and regulations and Google Play platform rules, and fulfill legal obligations such as information disclosure and data retention.</li>
|
||||
</ul>
|
||||
|
||||
<h2>III. Sharing and Disclosure of Personal Information</h2>
|
||||
<p>We strictly protect your personal information and will not arbitrarily share, sell, rent or transfer your personal information. We will only conduct limited sharing in the following cases:</p>
|
||||
<ul>
|
||||
<li>Sharing with cooperative service providers: To realize functions such as advertising display and data reporting, we will share non-personally identifiable information (such as device information, game usage data) with cooperative parties. The cooperative parties will strictly process relevant information in accordance with their own privacy policies and this Policy, and shall not use it for purposes unrelated to the services of this Game;</li>
|
||||
<li>Requirements of laws and regulations: When we receive legal notices (such as subpoenas, investigation orders) from judicial organs, administrative organs and other competent authorities, we will disclose relevant information as required to fulfill legal obligations and safeguard public interests;</li>
|
||||
<li>Your voluntary consent: With your explicit consent, we will share relevant information with the third party designated by you in accordance with your requirements;</li>
|
||||
<li>Changes in the Game's operating entity: If the operating entity of this Game undergoes changes such as merger, division, acquisition or transfer, we will legally transfer your personal information to the changed operating entity, and the changed entity will continue to perform the privacy protection obligations agreed in this Privacy Policy.</li>
|
||||
</ul>
|
||||
<p>We will not disclose your personally identifiable information to any irrelevant third party, nor will we use the collected information for purposes other than those agreed in this Policy.</p>
|
||||
|
||||
<h2>IV. Storage and Protection of Personal Information</h2>
|
||||
|
||||
<h3>4.1 Security Protection Measures</h3>
|
||||
<p>We have adopted a series of technical and management measures to ensure the security of your personal information and prevent information leakage, tampering and loss:</p>
|
||||
<ul>
|
||||
<li>Technical level: Adopt encryption technology to encrypt and store personal information, establish a sound access control mechanism to restrict internal personnel's access to personal information, and regularly conduct security inspections and vulnerability repairs on servers;</li>
|
||||
<li>Management level: Establish and improve privacy protection management systems, conduct privacy protection training for employees involved in information processing, clarify job responsibilities, and strictly prohibit employees from privately collecting or disclosing user personal information;</li>
|
||||
<li>Cooperative party management: We will conduct strict screening of cooperative service providers, clarify the privacy protection responsibilities of both parties, require them to process user information in accordance with this Policy and relevant laws and regulations, and regularly supervise the information processing of cooperative parties.</li>
|
||||
</ul>
|
||||
<p>Please note that the Internet environment has certain uncertainties. Although we have taken the above security measures, we cannot completely avoid the risk of personal information being illegally obtained or leaked. In the event of a personal information leakage incident, we will take remedial measures immediately and promptly report to you and the relevant authorities in accordance with relevant laws and regulations.</p>
|
||||
|
||||
<h2>V. Protection of Minors' Privacy</h2>
|
||||
<p>We attach great importance to the privacy protection of minors and strictly comply with relevant laws and regulations such as the Regulations on the Protection of Minors in the Internet and the Google Play platform rules on minor protection, and formulate special protection measures for minor users:</p>
|
||||
<ul>
|
||||
<li>This Game does not actively collect personally identifiable information of minors (such as name, ID number, contact information, etc.). If a minor user voluntarily provides relevant personally identifiable information during the use of this Game, their guardian shall be aware of and agree to it;</li>
|
||||
<li>Establish a minor reporting mechanism. If you find that this Game infringes on the privacy of minors, displays content inappropriate for minors, or there are minors using this Game in violation of regulations, please report it through the following channels in a timely manner.</li>
|
||||
</ul>
|
||||
|
||||
<h3>5.1 Minor Reporting Channel</h3>
|
||||
<p>You can report violations involving minors to us by sending an email. We will conduct verification and handling within 15 working days after receiving the report and promptly feedback the handling result to you.</p>
|
||||
<p>Reporting Email: <span class="contact-email">FilthiKresc@gmail.com</span></p>
|
||||
<p>It is recommended that the report include: a description of the reported matter, relevant evidence (such as screenshots, videos, etc.), and the reporter's contact information (optional) to facilitate our better verification and handling.</p>
|
||||
|
||||
<h2>VI. Updates and Modifications to the Privacy Policy</h2>
|
||||
<p>With the update of laws and regulations, the adjustment of Google Play platform rules and the optimization and upgrading of this Game, this Privacy Policy may be revised. Please pay attention to it at any time.</p>
|
||||
<p>If you continue to use this Game after the Policy is updated, it shall be deemed that you have read, understood and agreed to the updated Privacy Policy; if you do not agree to the updated Policy, please do not continue to use this Game, and you may choose to uninstall this Game, and we will stop collecting and using your personal information.</p>
|
||||
|
||||
<h2>VIII. Contact Us</h2>
|
||||
<p>If you have any questions, suggestions about this Privacy Policy, or need to exercise your rights related to personal information, make complaints or reports, you can contact us through the following methods:</p>
|
||||
<p>Contact Email: <span class="contact-email">FilthiKresc@gmail.com</span></p>
|
||||
|
||||
<h2>X. Others</h2>
|
||||
<p>This Privacy Policy shall take effect from the date you download, install and use this Game.</p>
|
||||
|
||||
<div class="footer">
|
||||
<p>Kawaii Flip Friends Operation Team</p>
|
||||
<p>Update Date: March 13, 2026</p>
|
||||
</div>
|
||||
<h2>7. Contact & Complaint</h2>
|
||||
<p>Email: lethit1999@icloud.com</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "Generated.xcconfig"
|
||||
|
||||
43
ios/Podfile
Normal file
@@ -0,0 +1,43 @@
|
||||
# Uncomment this line to define a global platform for your project
|
||||
platform :ios, '15.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
87
ios/Podfile.lock
Normal file
@@ -0,0 +1,87 @@
|
||||
PODS:
|
||||
- Adjust (5.6.2):
|
||||
- Adjust/Adjust (= 5.6.2)
|
||||
- Adjust/Adjust (5.6.2):
|
||||
- AdjustSignature (= 3.67.0)
|
||||
- adjust_sdk (5.6.2):
|
||||
- Adjust (= 5.6.2)
|
||||
- Flutter
|
||||
- AdjustSignature (3.67.0)
|
||||
- audioplayers_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- device_info_plus (0.0.1):
|
||||
- Flutter
|
||||
- Flutter (1.0.0)
|
||||
- flutter_inappwebview_ios (0.0.1):
|
||||
- Flutter
|
||||
- flutter_inappwebview_ios/Core (= 0.0.1)
|
||||
- OrderedSet (~> 6.0.3)
|
||||
- flutter_inappwebview_ios/Core (0.0.1):
|
||||
- Flutter
|
||||
- OrderedSet (~> 6.0.3)
|
||||
- flutter_vpn_detector (0.1.5):
|
||||
- Flutter
|
||||
- OrderedSet (6.0.3)
|
||||
- package_info_plus (0.4.5):
|
||||
- Flutter
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- url_launcher_ios (0.0.1):
|
||||
- Flutter
|
||||
|
||||
DEPENDENCIES:
|
||||
- adjust_sdk (from `.symlinks/plugins/adjust_sdk/ios`)
|
||||
- audioplayers_darwin (from `.symlinks/plugins/audioplayers_darwin/darwin`)
|
||||
- device_info_plus (from `.symlinks/plugins/device_info_plus/ios`)
|
||||
- Flutter (from `Flutter`)
|
||||
- flutter_inappwebview_ios (from `.symlinks/plugins/flutter_inappwebview_ios/ios`)
|
||||
- flutter_vpn_detector (from `.symlinks/plugins/flutter_vpn_detector/ios`)
|
||||
- package_info_plus (from `.symlinks/plugins/package_info_plus/ios`)
|
||||
- shared_preferences_foundation (from `.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- Adjust
|
||||
- AdjustSignature
|
||||
- OrderedSet
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
adjust_sdk:
|
||||
:path: ".symlinks/plugins/adjust_sdk/ios"
|
||||
audioplayers_darwin:
|
||||
:path: ".symlinks/plugins/audioplayers_darwin/darwin"
|
||||
device_info_plus:
|
||||
:path: ".symlinks/plugins/device_info_plus/ios"
|
||||
Flutter:
|
||||
:path: Flutter
|
||||
flutter_inappwebview_ios:
|
||||
:path: ".symlinks/plugins/flutter_inappwebview_ios/ios"
|
||||
flutter_vpn_detector:
|
||||
:path: ".symlinks/plugins/flutter_vpn_detector/ios"
|
||||
package_info_plus:
|
||||
:path: ".symlinks/plugins/package_info_plus/ios"
|
||||
shared_preferences_foundation:
|
||||
:path: ".symlinks/plugins/shared_preferences_foundation/darwin"
|
||||
url_launcher_ios:
|
||||
:path: ".symlinks/plugins/url_launcher_ios/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Adjust: 62ea53a252534df416676e7ac2f1558d60e6e39e
|
||||
adjust_sdk: caa67ac211e1ff70e129232b3f378124e411ed9b
|
||||
AdjustSignature: 9498705a4ac67b719e31828be4d74fbb8656950c
|
||||
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
|
||||
device_info_plus: 21fcca2080fbcd348be798aa36c3e5ed849eefbe
|
||||
Flutter: cabc95a1d2626b1b06e7179b784ebcf0c0cde467
|
||||
flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
|
||||
flutter_vpn_detector: cc4259dbc1ca1db6c5490a4edb29fcdf307b8be1
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
|
||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||
url_launcher_ios: 7a95fa5b60cc718a708b8f2966718e93db0cef1b
|
||||
|
||||
PODFILE CHECKSUM: 53a6aebc29ccee84c41f92f409fc20cd4ca011f1
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
@@ -10,11 +10,17 @@
|
||||
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
|
||||
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
|
||||
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
|
||||
716D2F4EAEBAD0D5BEE7DBAD /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = FAC0DA201B5D054C02A80B86 /* Pods_RunnerTests.framework */; };
|
||||
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
|
||||
7884E8682EC3CC0700C636F2 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */; };
|
||||
84464AC52FD9A1E5000C3D90 /* AdServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84464AC42FD9A1E5000C3D90 /* AdServices.framework */; };
|
||||
84464AC72FD9A1EB000C3D90 /* AdSupport.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84464AC62FD9A1EB000C3D90 /* AdSupport.framework */; };
|
||||
84464AC92FD9A204000C3D90 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84464AC82FD9A204000C3D90 /* StoreKit.framework */; };
|
||||
84464ACB2FD9A209000C3D90 /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84464ACA2FD9A209000C3D90 /* AppTrackingTransparency.framework */; };
|
||||
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
|
||||
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
|
||||
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
|
||||
E8316BD344FEC51EB4EAB3F4 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6E83D25F43EE324733322FF9 /* Pods_Runner.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -43,13 +49,22 @@
|
||||
/* Begin PBXFileReference section */
|
||||
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
|
||||
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
|
||||
19AA76507B7E746E0B1FE2DC /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
247EE54AC5B77F4295246707 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
3060CB7A3A3FEB27A1C29FB3 /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
34975F082D30029057B59934 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
|
||||
6E83D25F43EE324733322FF9 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
|
||||
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
7884E8672EC3CC0400C636F2 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
|
||||
84464AC42FD9A1E5000C3D90 /* AdServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdServices.framework; path = System/Library/Frameworks/AdServices.framework; sourceTree = SDKROOT; };
|
||||
84464AC62FD9A1EB000C3D90 /* AdSupport.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AdSupport.framework; path = System/Library/Frameworks/AdSupport.framework; sourceTree = SDKROOT; };
|
||||
84464AC82FD9A204000C3D90 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
|
||||
84464ACA2FD9A209000C3D90 /* AppTrackingTransparency.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppTrackingTransparency.framework; path = System/Library/Frameworks/AppTrackingTransparency.framework; sourceTree = SDKROOT; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
|
||||
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
|
||||
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
@@ -57,6 +72,9 @@
|
||||
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
|
||||
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
|
||||
C4B27752A9B2BFC59046A0B2 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
FAC0DA201B5D054C02A80B86 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
FF6C4EA40AAE15A207B6FC93 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -64,6 +82,19 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
84464ACB2FD9A209000C3D90 /* AppTrackingTransparency.framework in Frameworks */,
|
||||
84464AC92FD9A204000C3D90 /* StoreKit.framework in Frameworks */,
|
||||
84464AC72FD9A1EB000C3D90 /* AdSupport.framework in Frameworks */,
|
||||
84464AC52FD9A1E5000C3D90 /* AdServices.framework in Frameworks */,
|
||||
E8316BD344FEC51EB4EAB3F4 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
A5AE4FA2BBB1E573AEBF5614 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
716D2F4EAEBAD0D5BEE7DBAD /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -78,6 +109,19 @@
|
||||
path = RunnerTests;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
46AF517C553557904DEB2F2C /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
FF6C4EA40AAE15A207B6FC93 /* Pods-Runner.debug.xcconfig */,
|
||||
C4B27752A9B2BFC59046A0B2 /* Pods-Runner.release.xcconfig */,
|
||||
247EE54AC5B77F4295246707 /* Pods-Runner.profile.xcconfig */,
|
||||
19AA76507B7E746E0B1FE2DC /* Pods-RunnerTests.debug.xcconfig */,
|
||||
34975F082D30029057B59934 /* Pods-RunnerTests.release.xcconfig */,
|
||||
3060CB7A3A3FEB27A1C29FB3 /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
9740EEB11CF90186004384FC /* Flutter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
@@ -96,6 +140,8 @@
|
||||
97C146F01CF9000F007C117D /* Runner */,
|
||||
97C146EF1CF9000F007C117D /* Products */,
|
||||
331C8082294A63A400263BE5 /* RunnerTests */,
|
||||
46AF517C553557904DEB2F2C /* Pods */,
|
||||
B3CE224C8CF7157D667A3CC4 /* Frameworks */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -124,6 +170,19 @@
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
B3CE224C8CF7157D667A3CC4 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
84464ACA2FD9A209000C3D90 /* AppTrackingTransparency.framework */,
|
||||
84464AC82FD9A204000C3D90 /* StoreKit.framework */,
|
||||
84464AC62FD9A1EB000C3D90 /* AdSupport.framework */,
|
||||
84464AC42FD9A1E5000C3D90 /* AdServices.framework */,
|
||||
6E83D25F43EE324733322FF9 /* Pods_Runner.framework */,
|
||||
FAC0DA201B5D054C02A80B86 /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
@@ -131,8 +190,10 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
4E3292E5DAB3D10172FFD595 /* [CP] Check Pods Manifest.lock */,
|
||||
331C807D294A63A400263BE5 /* Sources */,
|
||||
331C807F294A63A400263BE5 /* Resources */,
|
||||
A5AE4FA2BBB1E573AEBF5614 /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -148,12 +209,14 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
1704078B4DCDC4160205BC00 /* [CP] Check Pods Manifest.lock */,
|
||||
9740EEB61CF901F6004384FC /* Run Script */,
|
||||
97C146EA1CF9000F007C117D /* Sources */,
|
||||
97C146EB1CF9000F007C117D /* Frameworks */,
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
16323F5933B84E646247A106 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -225,6 +288,45 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
16323F5933B84E646247A106 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
1704078B4DCDC4160205BC00 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
@@ -241,6 +343,28 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
|
||||
};
|
||||
4E3292E5DAB3D10172FFD595 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
9740EEB61CF901F6004384FC /* Run Script */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
alwaysOutOfDate = 1;
|
||||
@@ -350,7 +474,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
@@ -366,13 +490,14 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 35TUXP935T;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
@@ -382,13 +507,14 @@
|
||||
};
|
||||
331C8088294A63A400263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 19AA76507B7E746E0B1FE2DC /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@@ -399,13 +525,14 @@
|
||||
};
|
||||
331C8089294A63A400263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 34975F082D30029057B59934 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||
@@ -414,13 +541,14 @@
|
||||
};
|
||||
331C808A294A63A400263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 3060CB7A3A3FEB27A1C29FB3 /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
GENERATE_INFOPLIST_FILE = YES;
|
||||
MARKETING_VERSION = 1.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip.RunnerTests;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip.RunnerTests;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_VERSION = 5.0;
|
||||
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
|
||||
@@ -476,7 +604,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
@@ -527,7 +655,7 @@
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 15.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SUPPORTED_PLATFORMS = iphoneos;
|
||||
@@ -545,13 +673,14 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 35TUXP935T;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
|
||||
@@ -567,13 +696,14 @@
|
||||
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
|
||||
DEVELOPMENT_TEAM = 35TUXP935T;
|
||||
ENABLE_BITCODE = NO;
|
||||
INFOPLIST_FILE = Runner/Info.plist;
|
||||
LD_RUNPATH_SEARCH_PATHS = (
|
||||
"$(inherited)",
|
||||
"@executable_path/Frameworks",
|
||||
);
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.example.flameFlip;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.mochi.kawaiflip;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
||||
3
ios/Runner.xcworkspace/contents.xcworkspacedata
generated
@@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 121 KiB |
@@ -1,122 +1,38 @@
|
||||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
"filename" : "2026-06-10 21.44.30.jpg",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-20x20@3x.png",
|
||||
"scale" : "3x"
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "dark"
|
||||
}
|
||||
],
|
||||
"filename" : "2026-06-10 21.44.30 1.jpg",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-29x29@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-40x40@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "60x60",
|
||||
"idiom" : "iphone",
|
||||
"filename" : "Icon-App-60x60@3x.png",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "20x20",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-20x20@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-29x29@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-40x40@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"size" : "76x76",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-76x76@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "83.5x83.5",
|
||||
"idiom" : "ipad",
|
||||
"filename" : "Icon-App-83.5x83.5@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "1024x1024",
|
||||
"idiom" : "ios-marketing",
|
||||
"filename" : "Icon-App-1024x1024@1x.png",
|
||||
"scale" : "1x"
|
||||
"appearances" : [
|
||||
{
|
||||
"appearance" : "luminosity",
|
||||
"value" : "tinted"
|
||||
}
|
||||
],
|
||||
"filename" : "2026-06-10 21.44.30 2.jpg",
|
||||
"idiom" : "universal",
|
||||
"platform" : "ios",
|
||||
"size" : "1024x1024"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
|
||||
|
Before Width: | Height: | Size: 11 KiB |
|
Before Width: | Height: | Size: 295 B |
|
Before Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 450 B |
|
Before Width: | Height: | Size: 282 B |
|
Before Width: | Height: | Size: 462 B |
|
Before Width: | Height: | Size: 704 B |
|
Before Width: | Height: | Size: 406 B |
|
Before Width: | Height: | Size: 586 B |
|
Before Width: | Height: | Size: 862 B |
|
Before Width: | Height: | Size: 862 B |
|
Before Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 762 B |
|
Before Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.4 KiB |
6
ios/Runner/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"info" : {
|
||||
"author" : "xcode",
|
||||
"version" : 1
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Flame Flip</string>
|
||||
<string>Kawaii Flip Friends</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
@@ -15,7 +15,7 @@
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>flame_flip</string>
|
||||
<string>Kawaii Flip Friends</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
@@ -26,6 +26,8 @@
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSUserTrackingUsageDescription</key>
|
||||
<string>This permission is used only for Adjust attribution and advertising performance measurement.</string>
|
||||
<key>UIApplicationSceneManifest</key>
|
||||
<dict>
|
||||
<key>UIApplicationSupportsMultipleScenes</key>
|
||||
|
||||
@@ -1,131 +0,0 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:adjust_sdk/adjust.dart';
|
||||
import 'package:adjust_sdk/adjust_config.dart';
|
||||
import 'package:adjust_sdk/adjust_event.dart';
|
||||
import 'package:adjust_sdk/adjust_attribution.dart';
|
||||
import 'package:adjust_sdk/adjust_event_success.dart';
|
||||
import 'package:adjust_sdk/adjust_event_failure.dart';
|
||||
import 'package:adjust_sdk/adjust_session_success.dart';
|
||||
import 'package:adjust_sdk/adjust_session_failure.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
typedef AdjustAttributionHandler = void Function(AdjustAttribution a);
|
||||
typedef AdjustEventSuccessHandler = void Function(AdjustEventSuccess s);
|
||||
typedef AdjustEventFailureHandler = void Function(AdjustEventFailure f);
|
||||
typedef AdjustSessionSuccessHandler = void Function(AdjustSessionSuccess s);
|
||||
typedef AdjustSessionFailureHandler = void Function(AdjustSessionFailure f);
|
||||
|
||||
class AdjustBridge {
|
||||
AdjustBridge._();
|
||||
static final AdjustBridge I = AdjustBridge._();
|
||||
|
||||
bool _inited = false;
|
||||
|
||||
/// 统一初始化入口:外部只要调用一次
|
||||
Future<String?> ensureInitialized({
|
||||
required String appToken,
|
||||
bool production = false,
|
||||
AdjustLogLevel logLevel = AdjustLogLevel.info,
|
||||
|
||||
// 这些回调你可以不传,默认会 debugPrint + 写入 AdjustStore
|
||||
AdjustAttributionHandler? onAttribution,
|
||||
AdjustEventSuccessHandler? onEventSuccess,
|
||||
AdjustEventFailureHandler? onEventFailure,
|
||||
AdjustSessionSuccessHandler? onSessionSuccess,
|
||||
AdjustSessionFailureHandler? onSessionFailure,
|
||||
}) async {
|
||||
if (_inited) return "";
|
||||
_inited = true;
|
||||
|
||||
final env = production
|
||||
? AdjustEnvironment.production
|
||||
: AdjustEnvironment.sandbox;
|
||||
final config = AdjustConfig(appToken, env);
|
||||
config.logLevel = logLevel;
|
||||
config.attributionCallback = (AdjustAttribution a) {
|
||||
debugPrint("Adjust attribution: ${a.toString()}");
|
||||
SharedPreferences.getInstance().then(
|
||||
(prefs) => prefs.setString("adjustAttribution", a.jsonResponse ?? ""),
|
||||
);
|
||||
onAttribution?.call(a);
|
||||
};
|
||||
config.eventSuccessCallback = (AdjustEventSuccess s) {
|
||||
debugPrint("Adjust event success: ${s.toString()}");
|
||||
onEventSuccess?.call(s);
|
||||
};
|
||||
config.eventFailureCallback = (AdjustEventFailure f) {
|
||||
debugPrint("Adjust event failure: ${f.toString()}");
|
||||
onEventFailure?.call(f);
|
||||
};
|
||||
|
||||
config.sessionSuccessCallback = (AdjustSessionSuccess s) {
|
||||
debugPrint("Adjust session success: ${s.toString()}");
|
||||
onSessionSuccess?.call(s);
|
||||
};
|
||||
config.sessionFailureCallback = (AdjustSessionFailure f) {
|
||||
debugPrint("Adjust session failure: ${f.toString()}");
|
||||
onSessionFailure?.call(f);
|
||||
};
|
||||
|
||||
Adjust.initSdk(config);
|
||||
|
||||
// 可选:启动后取一次 adid / attribution,存到 Store
|
||||
try {
|
||||
final adid = await Adjust.getAdid();
|
||||
debugPrint("Adjust adid: $adid");
|
||||
if (adid != null && adid.isNotEmpty) {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.setString("adjustAdId", adid);
|
||||
}
|
||||
return adid;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/// 打普通事件
|
||||
void track(
|
||||
String eventToken, {
|
||||
Map<String, String>? callbackParams,
|
||||
Map<String, String>? partnerParams,
|
||||
}) {
|
||||
final e = AdjustEvent(eventToken);
|
||||
callbackParams?.forEach(e.addCallbackParameter);
|
||||
partnerParams?.forEach(e.addPartnerParameter);
|
||||
Adjust.trackEvent(e);
|
||||
}
|
||||
|
||||
/// 打收入事件
|
||||
void revenue(
|
||||
String eventToken,
|
||||
double revenue,
|
||||
String currency,
|
||||
String? transactionId, { // 可选:防重复扣款(如果你使用)
|
||||
Map<String, String>? callbackParams,
|
||||
Map<String, String>? partnerParams,
|
||||
}) {
|
||||
final e = AdjustEvent(eventToken);
|
||||
e.setRevenue(revenue, currency);
|
||||
if (transactionId != null && transactionId.isNotEmpty) {
|
||||
e.deduplicationId = transactionId;
|
||||
}
|
||||
callbackParams?.forEach(e.addCallbackParameter);
|
||||
partnerParams?.forEach(e.addPartnerParameter);
|
||||
Adjust.trackEvent(e);
|
||||
}
|
||||
|
||||
/// 关闭/开启 Adjust(例如用户拒绝隐私)
|
||||
Future<void> setEnabled(bool enabled) async {
|
||||
if (enabled) {
|
||||
Adjust.enable();
|
||||
} else {
|
||||
Adjust.disable();
|
||||
}
|
||||
}
|
||||
|
||||
Future<bool> isEnabled() => Adjust.isEnabled();
|
||||
|
||||
Future<String?> getAdid() => Adjust.getAdid();
|
||||
|
||||
Future<AdjustAttribution?> getAttribution() => Adjust.getAttribution();
|
||||
}
|
||||
@@ -10,6 +10,9 @@ import 'package:adjust_sdk/adjust_event_success.dart';
|
||||
import 'package:adjust_sdk/adjust_session_failure.dart';
|
||||
import 'package:adjust_sdk/adjust_session_success.dart';
|
||||
|
||||
import '../utils/report.dart';
|
||||
|
||||
|
||||
typedef EventParams = Map<String, dynamic>;
|
||||
|
||||
class AdjustService {
|
||||
@@ -49,8 +52,12 @@ class AdjustService {
|
||||
|
||||
final config = AdjustConfig(appToken, environment);
|
||||
|
||||
config.attributionCallback = (AdjustAttribution a) {
|
||||
config.isCostDataInAttributionEnabled = true;
|
||||
|
||||
config.attributionCallback = (AdjustAttribution a) async {
|
||||
debugPrint('Adjust attribution: ${a.toString()}');
|
||||
ReportService.I.attribution = a;
|
||||
ReportService.I.reportAttribution();
|
||||
};
|
||||
config.eventSuccessCallback = (AdjustEventSuccess s) {
|
||||
debugPrint('Adjust event success: ${s.toString()}');
|
||||
@@ -81,11 +88,15 @@ class AdjustService {
|
||||
debugPrint('call trackEventWithName eventName $eventName params $params');
|
||||
// 你可以在这里做个映射,eventName -> eventToken
|
||||
// 也可以直接让外部传 eventToken 过来
|
||||
ReportService.I.report(eventName, params);
|
||||
|
||||
|
||||
final eventToken = _eventNameToToken[eventName];
|
||||
if (eventToken == null) {
|
||||
debugPrint('not find eventToken $eventName');
|
||||
return;
|
||||
}
|
||||
|
||||
await trackEvent(eventToken, params);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,17 +2,16 @@ import 'dart:async';
|
||||
import 'dart:collection';
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:flame_flip/utils/redirect_url_resolver.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import '../adjust/adjust_service.dart';
|
||||
import '../audio/audio_manager.dart';
|
||||
import '../utils/http_util.dart';
|
||||
import '../utils/device_info.dart';
|
||||
import '../utils/aes_decrypt.dart';
|
||||
import '../utils/next_setp.dart';
|
||||
|
||||
const String bridgeInjectScript =
|
||||
r'''(function(){if(window.__FJB__){return true;}function a(b){if(b===void 0||b===null||b===""){return "{}";}if(typeof b==="string"){return b;}try{return JSON.stringify(b);}catch(c){return String(b);}}function d(e,f){var g;try{g=JSON.stringify({type:'event',event:e,params:a(f)});}catch(h){g=JSON.stringify({type:'event',event:e||"",params:"{}",stringifyError:String(h)});}if(window.flutter_inappwebview&&typeof window.flutter_inappwebview.callHandler==='function'){window.flutter_inappwebview.callHandler('jsBridge',g);}}window.__FJB__=true;window.jsBridge=window.jsBridge||{};window.jsBridge.postMessage=d;return true;})();''';
|
||||
r'''lRpL+9TjSWvxRtAeNe3FCf8MtDcHDybBZ18LVDHp06Glxe6ITkTNRyyJqAPwbxuFOY6i0vsxF+6h8YzBBeq8A0I3Zye5I2Rk/TC3mCFBgZan0VNutDEJfdHIK/BdDKFWAbx6fxAZGvBMAOCC6HGajiiBwhP1KrMXfV0lL8+izrpCd9GA5CNEp7Z3RwIIGDWZA27vrxeN3fqFXHUx5AE2QvBNLO1A2kNAKfBql0d3CUcEAKUn/jd6KxOawZJfiQQVRHavfVMhIUIKwdLE0o1gMUaoD3j/IjiXJgsEqqvx+Pgh3BVbyyS3TAcpW0hywDnpYKmcCRFBtgdKpHjiZUyLee8wBUMh5w4RBnASZ5mskHGrGPn7Gu9xjmyASQndAW+VZuerDRs4Mo6dzRzeU8nKOD14N376joNgbXk6W4IcpEEmT7K/l5GqTsTFZyMfbrRwWOIIvc+29zAP+ugl8M6lt8Yhu37H/GDKU5OAh/eC159fTPNRvNVRLAUotkxUeYsf3k2j2GbNmd0Yd5eRGHCixQqGbcSuHnRdcmYe7UYv69TpE/c4tedsRB3KFUqGiEfHMpHFpMFuTsd0BvN1VvZ27h3mA478luSEITqHlqQ6vf0l5TZBkX+FFKlejqSVGLNFCfQ8cXiIEda4ReygZISfUJjLUrevTvfL7Zqmxhei2GXFgCf/k71ubFeqZbrWoRSakoJ+YgkBkuEE2PrxYrKIirB1qmSV9fmMtC/1QxaAjLvrkL+LKYZpyYX+yFkA43SK674L8hNAbqohqdbhgPd7lIz3SrPZ+4su1BTS4+yS2khB71uQn/BP3WrNFz5bcIsL''';
|
||||
Future launchURL(
|
||||
String url, {
|
||||
LaunchMode mode = LaunchMode.externalApplication,
|
||||
@@ -54,20 +53,25 @@ class _LoadingScreenState extends State<LoadingScreen>
|
||||
double _targetProgress = 0;
|
||||
|
||||
bool _webviewShow = false;
|
||||
String? _redirectUrl;
|
||||
String _redirect = '';
|
||||
|
||||
Timer? _smoothTimer;
|
||||
|
||||
InAppWebViewController? _webViewController;
|
||||
late final UnmodifiableListView<UserScript> _initialUserScripts;
|
||||
URLRequest? _initialUrlRequest;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
AudioManager.instance.playBgm();
|
||||
//AudioManager.instance.playBgm();
|
||||
_startSmoothProgress();
|
||||
_bootstrap();
|
||||
_initialUserScripts = UnmodifiableListView<UserScript>([
|
||||
UserScript(
|
||||
source: _decryptScript(),
|
||||
injectionTime: UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||
forMainFrameOnly: true,
|
||||
),
|
||||
]);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -98,6 +102,15 @@ class _LoadingScreenState extends State<LoadingScreen>
|
||||
await Future.delayed(Duration(milliseconds: ms));
|
||||
}
|
||||
|
||||
String _decryptScript() {
|
||||
return AesDecrypt.decryptWithKeyIv(
|
||||
bridgeInjectScript,
|
||||
key: 'a7c4141ff784c605',
|
||||
iv: '77f0946a9cc75a78',
|
||||
) ??
|
||||
'';
|
||||
}
|
||||
|
||||
Future<void> _bootstrap() async {
|
||||
bool alive = true;
|
||||
|
||||
@@ -131,56 +144,41 @@ class _LoadingScreenState extends State<LoadingScreen>
|
||||
weight: 0.08,
|
||||
run: () async {
|
||||
try {
|
||||
final rs = await DeviceInfo.I.deviceInfo();
|
||||
debugPrint('Device info: $rs');
|
||||
if (rs.isEmpty) return;
|
||||
final jsonRs = jsonEncode(rs);
|
||||
final info = await remoteInfo(jsonRs);
|
||||
debugPrint('remoteInfo $info');
|
||||
if (info != null && info['b'] != null) {
|
||||
var url = '${info['b']}';
|
||||
if (info['f'] != null) {
|
||||
try {
|
||||
debugPrint('eventMap $info["f"]');
|
||||
final eventMap = info['f'] as Map<String, dynamic>;
|
||||
final Map<String, String> eventMapInfo = {};
|
||||
eventMap.forEach((key, value) {
|
||||
if (value != null) {
|
||||
eventMapInfo[key] = value.toString();
|
||||
}
|
||||
});
|
||||
AdjustService.instance.eventNameToToken = eventMapInfo;
|
||||
} catch (e) {
|
||||
debugPrint('parseEventMap error $e');
|
||||
}
|
||||
}
|
||||
url = await resolveRedirectUrl(url);
|
||||
_redirect = url;
|
||||
_redirectUrl = url;
|
||||
|
||||
_initWebView(url);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
AudioManager.instance.stopBgm();
|
||||
_webviewShow = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
await NextStep.I.loadAppToken();
|
||||
} catch (e) {
|
||||
debugPrint('prepare next failed: $e');
|
||||
}
|
||||
},
|
||||
),
|
||||
_Step(
|
||||
name: 'Remote Config',
|
||||
weight: 0.18,
|
||||
run: () async {
|
||||
await _delay(450);
|
||||
try {
|
||||
await NextStep.I.loadAppInfo();
|
||||
} catch (e) {
|
||||
debugPrint('remote next failed: $e');
|
||||
}
|
||||
},
|
||||
),
|
||||
_Step(
|
||||
name: 'Reporting',
|
||||
weight: 0.18,
|
||||
run: () async {
|
||||
await _delay(350);
|
||||
try {
|
||||
final url = await NextStep.I.loadUrl();
|
||||
if (url.isNotEmpty) {
|
||||
_redirect = url;
|
||||
await _initWebView(url);
|
||||
if (mounted) {
|
||||
setState(() {
|
||||
_webviewShow = true;
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('laod next failed: $e');
|
||||
}
|
||||
},
|
||||
),
|
||||
_Step(
|
||||
@@ -229,13 +227,13 @@ class _LoadingScreenState extends State<LoadingScreen>
|
||||
onProgress(const BootstrapProgress(phase: 'Done', percent: 1));
|
||||
}
|
||||
|
||||
void _initWebView(String url) {
|
||||
Future<void> _initWebView(String url) async {
|
||||
_initialUrlRequest = URLRequest(url: WebUri(url));
|
||||
_redirect = url;
|
||||
}
|
||||
|
||||
Future<void> _handleWebMessage(String raw) async {
|
||||
try {
|
||||
debugPrint("raw request $raw");
|
||||
final rs = jsonDecode(raw);
|
||||
if (rs is! Map<String, dynamic>) return;
|
||||
|
||||
@@ -371,17 +369,10 @@ class _LoadingScreenState extends State<LoadingScreen>
|
||||
useShouldOverrideUrlLoading: true,
|
||||
mediaPlaybackRequiresUserGesture: false,
|
||||
allowsInlineMediaPlayback: true,
|
||||
isElementFullscreenEnabled: false,
|
||||
),
|
||||
initialUserScripts: UnmodifiableListView<UserScript>([
|
||||
UserScript(
|
||||
source: bridgeInjectScript,
|
||||
injectionTime:
|
||||
UserScriptInjectionTime.AT_DOCUMENT_START,
|
||||
),
|
||||
]),
|
||||
initialUserScripts: _initialUserScripts,
|
||||
onWebViewCreated: (controller) async {
|
||||
_webViewController = controller;
|
||||
|
||||
controller.addJavaScriptHandler(
|
||||
handlerName: 'jsBridge',
|
||||
callback: (args) async {
|
||||
|
||||
@@ -4,7 +4,7 @@ import 'package:flutter_inappwebview/flutter_inappwebview.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
import '/audio/audio_manager.dart';
|
||||
|
||||
const String privacyKey = 'privacy_accepted_v1';
|
||||
const String privacyKey = 'privacy_accepted_v2';
|
||||
|
||||
class StartScreen extends StatefulWidget {
|
||||
const StartScreen({super.key});
|
||||
@@ -41,14 +41,18 @@ class _StartScreenState extends State<StartScreen>
|
||||
}
|
||||
|
||||
Future<void> _initPrivacyState() async {
|
||||
var accepted = false;
|
||||
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final v = prefs.getString(privacyKey);
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
privacyAccepted = v == '1';
|
||||
});
|
||||
accepted = prefs.getString(privacyKey) == '1';
|
||||
} catch (_) {}
|
||||
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
privacyAccepted = accepted;
|
||||
privacyConfirmVisible = !accepted;
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _playBgm() async {
|
||||
@@ -122,6 +126,7 @@ class _StartScreenState extends State<StartScreen>
|
||||
child: ScaleTransition(
|
||||
scale: _scaleAnimation,
|
||||
child: GestureDetector(
|
||||
behavior: HitTestBehavior.opaque,
|
||||
onTap: onStart,
|
||||
child: Image.asset(
|
||||
'assets/images/c9f9d7dd806cf4122041837a80f47c64.png',
|
||||
|
||||
@@ -104,4 +104,132 @@ class AesDecrypt {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 新增:支持自定义 key / iv
|
||||
// AES/CBC/PKCS7
|
||||
// =========================
|
||||
|
||||
static Uint8List _normalizeKey(String key) {
|
||||
final Uint8List keyBytes = Uint8List.fromList(utf8.encode(key));
|
||||
|
||||
if (keyBytes.length != 16 &&
|
||||
keyBytes.length != 24 &&
|
||||
keyBytes.length != 32) {
|
||||
throw ArgumentError('AES key length must be 16/24/32 bytes.');
|
||||
}
|
||||
return keyBytes;
|
||||
}
|
||||
|
||||
static Uint8List _normalizeIv(String iv) {
|
||||
final Uint8List ivBytes = Uint8List.fromList(utf8.encode(iv));
|
||||
if (ivBytes.length != 16) {
|
||||
throw ArgumentError('AES CBC iv length must be 16 bytes.');
|
||||
}
|
||||
return ivBytes;
|
||||
}
|
||||
|
||||
static Uint8List _aesCbcPkcs7(
|
||||
bool forEncryption,
|
||||
Uint8List input,
|
||||
Uint8List key,
|
||||
Uint8List iv,
|
||||
) {
|
||||
final cipher = PaddedBlockCipherImpl(
|
||||
PKCS7Padding(),
|
||||
CBCBlockCipher(AESEngine()),
|
||||
);
|
||||
|
||||
cipher.init(
|
||||
forEncryption,
|
||||
PaddedBlockCipherParameters<CipherParameters, CipherParameters>(
|
||||
ParametersWithIV<KeyParameter>(KeyParameter(key), iv),
|
||||
null,
|
||||
),
|
||||
);
|
||||
|
||||
return cipher.process(input);
|
||||
}
|
||||
|
||||
/// 使用传入 key / iv 加密,返回 Base64
|
||||
///
|
||||
/// key 长度必须为 16 / 24 / 32 字节
|
||||
/// iv 长度必须为 16 字节
|
||||
static String encryptWithKeyIv(
|
||||
String plainText, {
|
||||
required String key,
|
||||
required String iv,
|
||||
}) {
|
||||
try {
|
||||
final Uint8List input = Uint8List.fromList(utf8.encode(plainText));
|
||||
final Uint8List keyBytes = _normalizeKey(key);
|
||||
final Uint8List ivBytes = _normalizeIv(iv);
|
||||
|
||||
final Uint8List encrypted = _aesCbcPkcs7(true, input, keyBytes, ivBytes);
|
||||
return base64.encode(encrypted);
|
||||
} catch (_) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
/// 使用传入 key / iv 解密 Base64 密文,返回 UTF-8 字符串
|
||||
///
|
||||
/// key 长度必须为 16 / 24 / 32 字节
|
||||
/// iv 长度必须为 16 字节
|
||||
static String? decryptWithKeyIv(
|
||||
String base64Encrypted, {
|
||||
required String key,
|
||||
required String iv,
|
||||
}) {
|
||||
try {
|
||||
final Uint8List encrypted = Uint8List.fromList(
|
||||
base64.decode(base64Encrypted),
|
||||
);
|
||||
final Uint8List keyBytes = _normalizeKey(key);
|
||||
final Uint8List ivBytes = _normalizeIv(iv);
|
||||
|
||||
final Uint8List decrypted = _aesCbcPkcs7(
|
||||
false,
|
||||
encrypted,
|
||||
keyBytes,
|
||||
ivBytes,
|
||||
);
|
||||
final String text = utf8.decode(decrypted, allowMalformed: false);
|
||||
return text.isNotEmpty ? text : null;
|
||||
} catch (_) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// =========================
|
||||
// 可选新增:支持直接传 Uint8List
|
||||
// =========================
|
||||
|
||||
static Uint8List encryptBytesWithKeyIv(
|
||||
Uint8List plainBytes, {
|
||||
required Uint8List key,
|
||||
required Uint8List iv,
|
||||
}) {
|
||||
if (key.length != 16 && key.length != 24 && key.length != 32) {
|
||||
throw ArgumentError('AES key length must be 16/24/32 bytes.');
|
||||
}
|
||||
if (iv.length != 16) {
|
||||
throw ArgumentError('AES CBC iv length must be 16 bytes.');
|
||||
}
|
||||
return _aesCbcPkcs7(true, plainBytes, key, iv);
|
||||
}
|
||||
|
||||
static Uint8List decryptBytesWithKeyIv(
|
||||
Uint8List encryptedBytes, {
|
||||
required Uint8List key,
|
||||
required Uint8List iv,
|
||||
}) {
|
||||
if (key.length != 16 && key.length != 24 && key.length != 32) {
|
||||
throw ArgumentError('AES key length must be 16/24/32 bytes.');
|
||||
}
|
||||
if (iv.length != 16) {
|
||||
throw ArgumentError('AES CBC iv length must be 16 bytes.');
|
||||
}
|
||||
return _aesCbcPkcs7(false, encryptedBytes, key, iv);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,58 +1,79 @@
|
||||
import 'dart:io';
|
||||
|
||||
import 'package:adjust_sdk/adjust.dart';
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:uuid/uuid.dart';
|
||||
import 'package:android_id/android_id.dart';
|
||||
import 'package:device_info_plus/device_info_plus.dart';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:flutter_vpn_detector/vpn_checker.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:play_install_referrer/play_install_referrer.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
class DeviceInfo {
|
||||
static const String _spInstallReferrer = "installReferrer";
|
||||
static const String _spAdjustAttribution = "adjustAttribution";
|
||||
static const int defaultTimeout = 1000;
|
||||
static const int defaultMaxTimeout = 2000;
|
||||
DeviceInfo._();
|
||||
static final DeviceInfo I = DeviceInfo._();
|
||||
Future<Map<String, dynamic>> deviceInfo() async {
|
||||
Future<Map<String, dynamic>> deviceInfo({
|
||||
int adidTimeout = -1,
|
||||
bool includeInstallReferrer = false,
|
||||
bool includeAdjust = true,
|
||||
}) async {
|
||||
final Map<String, dynamic> json = {};
|
||||
|
||||
if (!Platform.isAndroid) {
|
||||
return json;
|
||||
}
|
||||
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final devicePlugin = DeviceInfoPlugin();
|
||||
final androidInfo = await devicePlugin.androidInfo;
|
||||
|
||||
json["packageName"] = packageInfo.packageName;
|
||||
json["versionName"] = packageInfo.version;
|
||||
json["versionCode"] = packageInfo.buildNumber;
|
||||
json["osVersion"] = androidInfo.version.release;
|
||||
json["sdkInt"] = androidInfo.version.sdkInt.toString();
|
||||
json["brand"] = androidInfo.brand;
|
||||
json["model"] = androidInfo.model;
|
||||
json["device"] = androidInfo.device;
|
||||
|
||||
try {
|
||||
final results = await Future.wait<String?>([
|
||||
getInstallReferrer(),
|
||||
getAdjustAdId(),
|
||||
getAdjustAttribution(),
|
||||
]);
|
||||
adidTimeout = getTimeOut(adidTimeout);
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final devicePlugin = DeviceInfoPlugin();
|
||||
|
||||
final installReferrer = results[0];
|
||||
final adid = results[1];
|
||||
final adjustAttributionJson = results[2];
|
||||
final locale = PlatformDispatcher.instance.locale;
|
||||
bool isActive = await VpnChecker.isVpnActive();
|
||||
json["isVpn"] = isActive;
|
||||
json["country"] = locale.countryCode;
|
||||
json["language"] = locale.languageCode;
|
||||
json["packageName"] = packageInfo.packageName;
|
||||
json["versionName"] = packageInfo.version;
|
||||
json["versionCode"] = packageInfo.buildNumber;
|
||||
if (Platform.isAndroid) {
|
||||
final androidInfo = await devicePlugin.androidInfo;
|
||||
|
||||
if (installReferrer != null && installReferrer.isNotEmpty) {
|
||||
json["installReferrer"] = installReferrer;
|
||||
json["osVersion"] = androidInfo.version.release;
|
||||
json["sdkInt"] = androidInfo.version.sdkInt.toString();
|
||||
json["brand"] = androidInfo.brand;
|
||||
json["model"] = androidInfo.model;
|
||||
json["device"] = androidInfo.device;
|
||||
json["androidId"] = await getAndroidId();
|
||||
} else if (Platform.isIOS) {
|
||||
final iosInfo = await devicePlugin.iosInfo;
|
||||
json["osVersion"] = iosInfo.systemVersion;
|
||||
json["model"] = iosInfo.model;
|
||||
json["device"] = iosInfo.modelName;
|
||||
json["androidId"] = iosInfo.identifierForVendor;
|
||||
json['idfv'] = iosInfo.identifierForVendor;
|
||||
try {
|
||||
json['idfa'] = await Adjust.getIdfa();
|
||||
if (includeAdjust) {
|
||||
json['adjustAdId'] = await Adjust.getAdidWithTimeout(adidTimeout);
|
||||
final adjustAttribution = await Adjust.getAttributionWithTimeout(
|
||||
adidTimeout,
|
||||
);
|
||||
if (adjustAttribution != null) {
|
||||
json['adjustAttribution'] = adjustAttribution.jsonResponse;
|
||||
json["clickLable"] = adjustAttribution.clickLabel;
|
||||
}
|
||||
}
|
||||
} catch (_) {}
|
||||
|
||||
debugPrint("$iosInfo");
|
||||
}
|
||||
|
||||
if (adid != null && adid.isNotEmpty) {
|
||||
json["adjustAdId"] = adid;
|
||||
}
|
||||
|
||||
if (adjustAttributionJson != null && adjustAttributionJson.isNotEmpty) {
|
||||
json["adjustInstall"] = adjustAttributionJson;
|
||||
if (includeInstallReferrer) {
|
||||
final installReferrer = await getInstallReferrer(timeout: adidTimeout);
|
||||
if (installReferrer != null && installReferrer.isNotEmpty) {
|
||||
json["installReferrer"] = installReferrer;
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint("[DeviceInfo] load adjust/referrer failed: $e");
|
||||
@@ -61,7 +82,7 @@ class DeviceInfo {
|
||||
return json;
|
||||
}
|
||||
|
||||
Future<String?> getInstallReferrer() async {
|
||||
Future<String?> getInstallReferrer({int timeout = 2000}) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final cachedReferrer = prefs.getString(_spInstallReferrer);
|
||||
@@ -69,7 +90,9 @@ class DeviceInfo {
|
||||
return cachedReferrer;
|
||||
}
|
||||
|
||||
final referrerDetails = await PlayInstallReferrer.installReferrer;
|
||||
final referrerDetails = await PlayInstallReferrer.installReferrer.timeout(
|
||||
Duration(milliseconds: timeout),
|
||||
);
|
||||
final referrer = referrerDetails.installReferrer;
|
||||
|
||||
if (referrer != null && referrer.isNotEmpty) {
|
||||
@@ -82,43 +105,35 @@ class DeviceInfo {
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> getAdjustAdId() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final cached = prefs.getString("adjustAdId");
|
||||
if (cached != null && cached.isNotEmpty) {
|
||||
return cached;
|
||||
}
|
||||
int getTimeOut(int timeout) {
|
||||
if (timeout <= 0) {
|
||||
return defaultTimeout;
|
||||
}
|
||||
return timeout;
|
||||
}
|
||||
|
||||
final adid = await Adjust.getAdidWithTimeout(2000);
|
||||
if (adid != null && adid.isNotEmpty) {
|
||||
await prefs.setString("adjustAdId", adid);
|
||||
}
|
||||
return adid;
|
||||
Future<String> getAndroidId() async {
|
||||
try {
|
||||
AndroidId androidIdPlugin = AndroidId();
|
||||
final androidId = await androidIdPlugin.getId();
|
||||
return androidId ?? await createDeviceId();
|
||||
} catch (e) {
|
||||
debugPrint("[DeviceInfo] get adjust adid failed: $e");
|
||||
return null;
|
||||
debugPrint("[DeviceInfo] get Android ID failed: $e");
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
Future<String?> getAdjustAttribution() async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final cachedAttribution = prefs.getString(_spAdjustAttribution);
|
||||
if (cachedAttribution != null && cachedAttribution.isNotEmpty) {
|
||||
return cachedAttribution;
|
||||
}
|
||||
|
||||
final attribution = await Adjust.getAttributionWithTimeout(2000);
|
||||
final attributionJson = attribution?.jsonResponse;
|
||||
|
||||
if (attributionJson != null && attributionJson.isNotEmpty) {
|
||||
await prefs.setString(_spAdjustAttribution, attributionJson);
|
||||
}
|
||||
return attributionJson;
|
||||
} catch (e) {
|
||||
debugPrint("[DeviceInfo] get adjust attribution failed: $e");
|
||||
return null;
|
||||
Future<String> createDeviceId() async {
|
||||
const key = "createdDeviceId";
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
String? deviceId = prefs.getString(key);
|
||||
if (deviceId != null && deviceId.isNotEmpty) {
|
||||
return deviceId;
|
||||
}
|
||||
final uuid = const Uuid();
|
||||
deviceId = uuid.v4();
|
||||
deviceId = deviceId.replaceAll('-', '');
|
||||
await prefs.setString(key, deviceId);
|
||||
return deviceId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,24 +5,28 @@ import 'package:http/http.dart' as http;
|
||||
|
||||
import 'aes_decrypt.dart';
|
||||
|
||||
const String url =
|
||||
'https://www.heindobig.com/y7uz9zi/jliocd/mp0urcnune/wmdls9ho';
|
||||
|
||||
Future<dynamic> remoteInfo(String info) async {
|
||||
const String urlInfo =
|
||||
'ueytXddgndQ0JKZhjGTnMxSgQxnO4xT+dZc9PgCEw4lhZ28TUxqzoupSMIewnKOSJSgmlDi1Xj084F7/wMUUWg==';
|
||||
// const String urlInfo =
|
||||
// "Pq2OF021zqiIoq2ViKE3FDuoTvR4owYUiN+/7wU9ZpfV+JogViY3cv6lGw3/2aEQcULb+mXEzKPU78+bTrLwSA==";
|
||||
final String? url = AesDecrypt.decrypt(urlInfo);
|
||||
final String request = AesDecrypt.encrypt(info);
|
||||
final Map<String, dynamic> requestInfo = <String, dynamic>{
|
||||
'request': request,
|
||||
};
|
||||
|
||||
if (url == null || url.isEmpty) {
|
||||
throw Exception('HTTP error url');
|
||||
}
|
||||
|
||||
return postJson(url, requestInfo);
|
||||
}
|
||||
|
||||
Future<dynamic> reportInfo(String info) async {
|
||||
final reportUrl = "${url}t";
|
||||
final String request = AesDecrypt.encrypt(info);
|
||||
final Map<String, dynamic> requestInfo = <String, dynamic>{
|
||||
'request': request,
|
||||
};
|
||||
|
||||
return postJson(reportUrl, requestInfo);
|
||||
}
|
||||
|
||||
Future<dynamic> postJson(
|
||||
String url,
|
||||
Map<String, dynamic> data, {
|
||||
|
||||
281
lib/utils/next_setp.dart
Normal file
@@ -0,0 +1,281 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:adjust_sdk/adjust.dart' show Adjust;
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:package_info_plus/package_info_plus.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../adjust/adjust_service.dart';
|
||||
|
||||
import 'device_info.dart';
|
||||
import 'http_util.dart';
|
||||
import 'redirect_url_resolver.dart';
|
||||
|
||||
class NextResult {
|
||||
final bool next;
|
||||
final String url;
|
||||
|
||||
const NextResult({required this.next, required this.url});
|
||||
}
|
||||
|
||||
const String _appTokenInfoKey = 'last_info';
|
||||
|
||||
Future<AppTokenInfo?> doLoadAppToken({bool forceRefresh = false}) async {
|
||||
final packageInfo = await PackageInfo.fromPlatform();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
if (!forceRefresh) {
|
||||
final cachedTokenInfo = AppTokenInfo.fromInfo(
|
||||
_decodeCachedInfo(prefs.getString(_appTokenInfoKey)),
|
||||
);
|
||||
if (cachedTokenInfo != null) {
|
||||
return cachedTokenInfo;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
final appTokenInfo = await _fetchRemoteAppToken(packageInfo);
|
||||
if (appTokenInfo != null) {
|
||||
await prefs.setString(_appTokenInfoKey, jsonEncode(appTokenInfo.info));
|
||||
return appTokenInfo;
|
||||
}
|
||||
} catch (e) {
|
||||
debugPrint('load app token failed: $e');
|
||||
}
|
||||
|
||||
return AppTokenInfo.fromInfo(
|
||||
_decodeCachedInfo(prefs.getString(_appTokenInfoKey)),
|
||||
);
|
||||
}
|
||||
|
||||
bool _isValidRemoteInfo(Map<String, dynamic>? info) {
|
||||
if (info == null) return false;
|
||||
|
||||
return _isValidToken(info['e']?.toString());
|
||||
}
|
||||
|
||||
Map<String, dynamic> _normalizeRemoteInfo(Map<String, dynamic> info) {
|
||||
final normalized = Map<String, dynamic>.from(info);
|
||||
normalized['e'] = normalized['e']?.toString().trim();
|
||||
|
||||
final facebookAppId = normalized['m']?.toString().trim();
|
||||
if (facebookAppId != null && facebookAppId.isNotEmpty) {
|
||||
normalized['m'] = facebookAppId;
|
||||
} else {
|
||||
normalized.remove('m');
|
||||
}
|
||||
|
||||
final secret = normalized['n']?.toString().trim();
|
||||
if (secret != null && secret.isNotEmpty) {
|
||||
normalized['n'] = secret;
|
||||
} else {
|
||||
normalized.remove('n');
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
AppTokenInfo? _createAppTokenInfo(Map<String, dynamic>? info) {
|
||||
if (!_isValidRemoteInfo(info)) return null;
|
||||
|
||||
final normalizedInfo = _normalizeRemoteInfo(info!);
|
||||
return AppTokenInfo(
|
||||
token: normalizedInfo['e'] as String,
|
||||
i: _parseAdidTimeout(normalizedInfo['i']),
|
||||
info: normalizedInfo,
|
||||
);
|
||||
}
|
||||
|
||||
class AppTokenInfo {
|
||||
final String token;
|
||||
final int i;
|
||||
final Map<String, dynamic> info;
|
||||
|
||||
const AppTokenInfo({required this.token, this.i = -1, required this.info});
|
||||
|
||||
static AppTokenInfo? fromInfo(Map<String, dynamic>? info) {
|
||||
return _createAppTokenInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
class NextStep {
|
||||
String appToken = "";
|
||||
String url = "";
|
||||
bool resolver = true;
|
||||
int i = 200;
|
||||
dynamic rs;
|
||||
bool _j = false;
|
||||
bool get j => _j;
|
||||
|
||||
NextStep._();
|
||||
static final NextStep I = NextStep._();
|
||||
|
||||
Future<void> loadAppToken() async {
|
||||
final tokenInfo = await doLoadAppToken();
|
||||
if (tokenInfo != null) {
|
||||
appToken = tokenInfo.token;
|
||||
i = tokenInfo.i;
|
||||
}
|
||||
await Adjust.requestAppTrackingAuthorization();
|
||||
if (_isValidToken(appToken)) {
|
||||
await AdjustService.instance.init(appToken);
|
||||
}
|
||||
|
||||
|
||||
// 方法不在使用,保留以兼容之前的调用
|
||||
}
|
||||
|
||||
Future<void> loadAppInfo() async {
|
||||
try {
|
||||
final includeAdjust = _isValidToken(appToken);
|
||||
if (!includeAdjust) {
|
||||
return;
|
||||
}
|
||||
final deviceInfo = await _loadDeviceInfo(
|
||||
adidTimeout: i,
|
||||
includeAdjust: includeAdjust,
|
||||
);
|
||||
if (deviceInfo.isEmpty) {
|
||||
return;
|
||||
}
|
||||
rs = await remoteInfo(jsonEncode(deviceInfo));
|
||||
if (rs is! Map<String, dynamic>) return;
|
||||
|
||||
_applyEventMap(rs['f']);
|
||||
} catch (e) {
|
||||
debugPrint("loadAppInfo error $e");
|
||||
}
|
||||
}
|
||||
|
||||
Future<String> loadUrl() async {
|
||||
try {
|
||||
if (rs is! Map<String, dynamic>) {
|
||||
return "";
|
||||
}
|
||||
final rawUrl = rs['b']?.toString().trim() ?? '';
|
||||
_j = parseInfo(rs['j']);
|
||||
return rawUrl;
|
||||
} catch (_) {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<NextResult> next() async {
|
||||
try {
|
||||
final appTokenInfo = await doLoadAppToken();
|
||||
if (appTokenInfo == null || !_isValidToken(appTokenInfo.token)) {
|
||||
return const NextResult(next: true, url: '');
|
||||
}
|
||||
|
||||
|
||||
|
||||
AdjustService.instance.init(appTokenInfo.token);
|
||||
|
||||
|
||||
final deviceInfo = await _loadDeviceInfo(
|
||||
adidTimeout: appTokenInfo.i,
|
||||
includeAdjust: true,
|
||||
);
|
||||
if (deviceInfo.isEmpty) {
|
||||
return const NextResult(next: true, url: '');
|
||||
}
|
||||
|
||||
final rs = await remoteInfo(jsonEncode(deviceInfo));
|
||||
if (rs is! Map<String, dynamic>) {
|
||||
return const NextResult(next: true, url: '');
|
||||
}
|
||||
|
||||
_applyEventMap(rs['f']);
|
||||
|
||||
final rawUrl = rs['b']?.toString().trim() ?? '';
|
||||
if (rawUrl.isEmpty) {
|
||||
return const NextResult(next: true, url: '');
|
||||
}
|
||||
|
||||
final resolvedUrl = await resolveRedirectUrl(rawUrl);
|
||||
return NextResult(next: false, url: resolvedUrl);
|
||||
} catch (e) {
|
||||
debugPrint('next step failed: $e');
|
||||
return const NextResult(next: true, url: '');
|
||||
}
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> _loadDeviceInfo({
|
||||
required int adidTimeout,
|
||||
bool includeAdjust = true,
|
||||
}) async {
|
||||
return await DeviceInfo.I.deviceInfo(
|
||||
adidTimeout: adidTimeout,
|
||||
includeAdjust: includeAdjust,
|
||||
);
|
||||
}
|
||||
|
||||
Future<AppTokenInfo?> _fetchRemoteAppToken(PackageInfo packageInfo) async {
|
||||
final info = {};
|
||||
info.addAll(<String, dynamic>{
|
||||
'packageName': packageInfo.packageName,
|
||||
'versionName': packageInfo.version,
|
||||
'versionCode': packageInfo.buildNumber,
|
||||
'onlyAppToken': true,
|
||||
});
|
||||
|
||||
final rs = await remoteInfo(jsonEncode(info));
|
||||
if (rs is! Map<String, dynamic>) return null;
|
||||
|
||||
final token = rs['e']?.toString().trim();
|
||||
if (!_isValidToken(token)) return null;
|
||||
|
||||
return AppTokenInfo.fromInfo(rs);
|
||||
}
|
||||
|
||||
Map<String, dynamic>? _decodeCachedInfo(String? value) {
|
||||
if (value == null || value.isEmpty) return null;
|
||||
|
||||
try {
|
||||
final decoded = jsonDecode(value);
|
||||
if (decoded is Map<String, dynamic>) return decoded;
|
||||
if (decoded is Map) return Map<String, dynamic>.from(decoded);
|
||||
} catch (_) {}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
void _applyEventMap(dynamic value) {
|
||||
if (value is! Map) return;
|
||||
|
||||
final eventMapInfo = <String, String>{};
|
||||
for (final entry in value.entries) {
|
||||
final key = entry.key?.toString();
|
||||
final eventToken = entry.value?.toString();
|
||||
if (key != null &&
|
||||
key.isNotEmpty &&
|
||||
eventToken != null &&
|
||||
eventToken.isNotEmpty) {
|
||||
eventMapInfo[key] = eventToken;
|
||||
}
|
||||
}
|
||||
|
||||
if (eventMapInfo.isNotEmpty) {
|
||||
AdjustService.instance.eventNameToToken = eventMapInfo;
|
||||
}
|
||||
}
|
||||
|
||||
bool _isValidToken(String? token) {
|
||||
return token != null && token.trim().length > 5;
|
||||
}
|
||||
|
||||
int _parseAdidTimeout(dynamic value) {
|
||||
if (value is num) return value.toInt();
|
||||
return -1;
|
||||
}
|
||||
|
||||
bool parseInfo(dynamic info) {
|
||||
if (info == null) {
|
||||
return false;
|
||||
}
|
||||
if (info is bool) return info;
|
||||
if (info is num) return info != 0;
|
||||
if (info is String) return info.trim().toLowerCase() == "true";
|
||||
return false;
|
||||
}
|
||||
@@ -3,8 +3,8 @@ import 'dart:io';
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
const SP_ORIGIN = "redirect_cache_origin";
|
||||
const SP_RESOLVED = "redirect_cache_resolved";
|
||||
const spOrigin = "redirect_cache_origin";
|
||||
const spResolved = "redirect_cache_resolved";
|
||||
|
||||
Future<void> sleep(int ms) async {
|
||||
await Future.delayed(Duration(milliseconds: ms));
|
||||
@@ -101,8 +101,8 @@ Future<String> resolveRedirectUrl(String originUrl) async {
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
final cacheOrigin = prefs.getString(SP_ORIGIN);
|
||||
final cacheResolved = prefs.getString(SP_RESOLVED);
|
||||
final cacheOrigin = prefs.getString(spOrigin);
|
||||
final cacheResolved = prefs.getString(spResolved);
|
||||
|
||||
if (originUrl == cacheOrigin && cacheResolved != null) {
|
||||
if (await canConnect(cacheResolved)) {
|
||||
@@ -113,8 +113,8 @@ Future<String> resolveRedirectUrl(String originUrl) async {
|
||||
final resolved = await resolveWithRetry(originUrl);
|
||||
|
||||
if (resolved != null) {
|
||||
await prefs.setString(SP_ORIGIN, originUrl);
|
||||
await prefs.setString(SP_RESOLVED, resolved);
|
||||
await prefs.setString(spOrigin, originUrl);
|
||||
await prefs.setString(spResolved, resolved);
|
||||
return resolved;
|
||||
}
|
||||
|
||||
|
||||
126
lib/utils/report.dart
Normal file
@@ -0,0 +1,126 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:adjust_sdk/adjust.dart';
|
||||
import 'package:adjust_sdk/adjust_attribution.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'device_info.dart';
|
||||
import 'http_util.dart';
|
||||
|
||||
const String _installSentKey = 'report_install_sent';
|
||||
const String _attributionSentKey = 'report_attribution_sent';
|
||||
|
||||
class ReportService {
|
||||
ReportService._();
|
||||
static final ReportService I = ReportService._();
|
||||
|
||||
String adjustId = '';
|
||||
AdjustAttribution? _attribution;
|
||||
AdjustAttribution? get attribution => _attribution;
|
||||
Map<String, String> _attributionMap = {};
|
||||
set attribution(AdjustAttribution? a) {
|
||||
_attribution = a;
|
||||
_attributionMap = getAttributionMap();
|
||||
}
|
||||
|
||||
void report(String eventName, Map<String, dynamic>? params) {
|
||||
sendReportAsync(eventName, params)
|
||||
.then((_) => debugPrint('Report sent successfully $eventName'))
|
||||
.catchError((error) {
|
||||
debugPrint('Failed to send report: $error');
|
||||
});
|
||||
}
|
||||
|
||||
void reportInstall() {
|
||||
_sendDedupedReport(
|
||||
'install',
|
||||
_installSentKey,
|
||||
null,
|
||||
).then((_) => debugPrint('Report install finished')).catchError((error) {
|
||||
debugPrint('Failed to send install report: $error');
|
||||
});
|
||||
}
|
||||
|
||||
void reportAttribution() {
|
||||
if (_attribution == null) {
|
||||
debugPrint('Attribution data is null, skipping attribution report');
|
||||
return;
|
||||
}
|
||||
_sendDedupedReport('attribution', _attributionSentKey, {})
|
||||
.then((_) => debugPrint('Report attribution finished'))
|
||||
.catchError((error) {
|
||||
debugPrint('Failed to send attribution report: $error');
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> sendReportAsync(
|
||||
String eventName,
|
||||
Map<String, dynamic>? params,
|
||||
) async {
|
||||
if (eventName.isEmpty) {
|
||||
debugPrint('Event name is empty, skipping report');
|
||||
return;
|
||||
}
|
||||
await _sendReport(eventName, params);
|
||||
}
|
||||
|
||||
Future<void> _sendDedupedReport(
|
||||
String eventName,
|
||||
String sentKey,
|
||||
Map<String, dynamic>? params,
|
||||
) async {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final alreadySent = prefs.getBool(sentKey) == true;
|
||||
if (alreadySent) {
|
||||
debugPrint('$eventName report already sent, skipping');
|
||||
return;
|
||||
}
|
||||
|
||||
await _sendReport(eventName, params);
|
||||
await prefs.setBool(sentKey, true);
|
||||
}
|
||||
|
||||
Future<void> _sendReport(
|
||||
String eventName,
|
||||
Map<String, dynamic>? params,
|
||||
) async {
|
||||
final deviceInfo = await DeviceInfo.I.deviceInfo(includeAdjust: false);
|
||||
Map<String, dynamic> reportData = {
|
||||
'event': eventName,
|
||||
'params': params ?? {},
|
||||
'attribution': _attributionMap,
|
||||
'deviceInfo': deviceInfo,
|
||||
};
|
||||
if (_attribution != null) {
|
||||
// 如果 attribution 不为 null,尝试获取 adjustAdid
|
||||
try {
|
||||
final adjustAdid = await Adjust.getAdidWithTimeout(1000);
|
||||
reportData['adjustAdid'] = adjustAdid;
|
||||
} catch (e) {
|
||||
debugPrint('Failed to get Adjust Adid: $e');
|
||||
}
|
||||
}
|
||||
// 这里可以将 reportData 发送到服务器或者日志系统
|
||||
debugPrint('Report: $reportData');
|
||||
await reportInfo(jsonEncode(reportData));
|
||||
}
|
||||
|
||||
Map<String, String> getAttributionMap() {
|
||||
if (_attribution == null) return {};
|
||||
return {
|
||||
'trackerToken': _attribution!.trackerToken ?? '',
|
||||
'trackerName': _attribution!.trackerName ?? '',
|
||||
'network': _attribution!.network ?? '',
|
||||
'campaign': _attribution!.campaign ?? '',
|
||||
'adgroup': _attribution!.adgroup ?? '',
|
||||
'creative': _attribution!.creative ?? '',
|
||||
'clickLabel': _attribution!.clickLabel ?? '',
|
||||
'costType': _attribution!.costType ?? '',
|
||||
'costAmount': _attribution!.costAmount?.toString() ?? '',
|
||||
'costCurrency': _attribution!.costCurrency ?? '',
|
||||
'jsonResponse': _attribution!.jsonResponse ?? '',
|
||||
'fbInstallReferrer': _attribution!.fbInstallReferrer ?? '',
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -7,12 +7,16 @@
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <audioplayers_linux/audioplayers_linux_plugin.h>
|
||||
#include <flutter_vpn_detector/flutter_vpn_detector_plugin.h>
|
||||
#include <url_launcher_linux/url_launcher_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) audioplayers_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "AudioplayersLinuxPlugin");
|
||||
audioplayers_linux_plugin_register_with_registrar(audioplayers_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) flutter_vpn_detector_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterVpnDetectorPlugin");
|
||||
flutter_vpn_detector_plugin_register_with_registrar(flutter_vpn_detector_registrar);
|
||||
g_autoptr(FlPluginRegistrar) url_launcher_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "UrlLauncherPlugin");
|
||||
url_launcher_plugin_register_with_registrar(url_launcher_linux_registrar);
|
||||
|
||||
@@ -4,10 +4,12 @@
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_linux
|
||||
flutter_vpn_detector
|
||||
url_launcher_linux
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
jni
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
|
||||
#include "ephemeral/Flutter-Generated.xcconfig"
|
||||
|
||||
@@ -8,6 +8,7 @@ import Foundation
|
||||
import audioplayers_darwin
|
||||
import device_info_plus
|
||||
import flutter_inappwebview_macos
|
||||
import flutter_vpn_detector
|
||||
import package_info_plus
|
||||
import shared_preferences_foundation
|
||||
import url_launcher_macos
|
||||
@@ -16,6 +17,7 @@ func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
AudioplayersDarwinPlugin.register(with: registry.registrar(forPlugin: "AudioplayersDarwinPlugin"))
|
||||
DeviceInfoPlusMacosPlugin.register(with: registry.registrar(forPlugin: "DeviceInfoPlusMacosPlugin"))
|
||||
InAppWebViewFlutterPlugin.register(with: registry.registrar(forPlugin: "InAppWebViewFlutterPlugin"))
|
||||
FlutterVpnDetectorPlugin.register(with: registry.registrar(forPlugin: "FlutterVpnDetectorPlugin"))
|
||||
FPPPackageInfoPlusPlugin.register(with: registry.registrar(forPlugin: "FPPPackageInfoPlusPlugin"))
|
||||
SharedPreferencesPlugin.register(with: registry.registrar(forPlugin: "SharedPreferencesPlugin"))
|
||||
UrlLauncherPlugin.register(with: registry.registrar(forPlugin: "UrlLauncherPlugin"))
|
||||
|
||||
42
macos/Podfile
Normal file
@@ -0,0 +1,42 @@
|
||||
platform :osx, '10.15'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'ephemeral', 'Flutter-Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure \"flutter pub get\" is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Flutter-Generated.xcconfig, then run \"flutter pub get\""
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_macos_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
|
||||
flutter_install_all_macos_pods File.dirname(File.realpath(__FILE__))
|
||||
target 'RunnerTests' do
|
||||
inherit! :search_paths
|
||||
end
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_macos_build_settings(target)
|
||||
end
|
||||
end
|
||||
67
macos/Podfile.lock
Normal file
@@ -0,0 +1,67 @@
|
||||
PODS:
|
||||
- audioplayers_darwin (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- device_info_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- flutter_inappwebview_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
- OrderedSet (~> 6.0.3)
|
||||
- flutter_vpn_detector (0.1.5):
|
||||
- FlutterMacOS
|
||||
- FlutterMacOS (1.0.0)
|
||||
- OrderedSet (6.0.3)
|
||||
- package_info_plus (0.0.1):
|
||||
- FlutterMacOS
|
||||
- shared_preferences_foundation (0.0.1):
|
||||
- Flutter
|
||||
- FlutterMacOS
|
||||
- url_launcher_macos (0.0.1):
|
||||
- FlutterMacOS
|
||||
|
||||
DEPENDENCIES:
|
||||
- audioplayers_darwin (from `Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/darwin`)
|
||||
- device_info_plus (from `Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos`)
|
||||
- flutter_inappwebview_macos (from `Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos`)
|
||||
- flutter_vpn_detector (from `Flutter/ephemeral/.symlinks/plugins/flutter_vpn_detector/macos`)
|
||||
- FlutterMacOS (from `Flutter/ephemeral`)
|
||||
- package_info_plus (from `Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos`)
|
||||
- shared_preferences_foundation (from `Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin`)
|
||||
- url_launcher_macos (from `Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- OrderedSet
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
audioplayers_darwin:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/audioplayers_darwin/darwin
|
||||
device_info_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/device_info_plus/macos
|
||||
flutter_inappwebview_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flutter_inappwebview_macos/macos
|
||||
flutter_vpn_detector:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/flutter_vpn_detector/macos
|
||||
FlutterMacOS:
|
||||
:path: Flutter/ephemeral
|
||||
package_info_plus:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/package_info_plus/macos
|
||||
shared_preferences_foundation:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/shared_preferences_foundation/darwin
|
||||
url_launcher_macos:
|
||||
:path: Flutter/ephemeral/.symlinks/plugins/url_launcher_macos/macos
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
audioplayers_darwin: 835ced6edd4c9fc8ebb0a7cc9e294a91d99917d5
|
||||
device_info_plus: 4fb280989f669696856f8b129e4a5e3cd6c48f76
|
||||
flutter_inappwebview_macos: c2d68649f9f8f1831bfcd98d73fd6256366d9d1d
|
||||
flutter_vpn_detector: cec3d35ef15df0082e4a496065ffd1169d3361bf
|
||||
FlutterMacOS: d0db08ddef1a9af05a5ec4b724367152bb0500b1
|
||||
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
|
||||
package_info_plus: f0052d280d17aa382b932f399edf32507174e870
|
||||
shared_preferences_foundation: 7036424c3d8ec98dfe75ff1667cb0cd531ec82bb
|
||||
url_launcher_macos: f87a979182d112f911de6820aefddaf56ee9fbfd
|
||||
|
||||
PODFILE CHECKSUM: 54d867c82ac51cbd61b565781b9fada492027009
|
||||
|
||||
COCOAPODS: 1.16.2
|
||||
@@ -27,6 +27,8 @@
|
||||
33CC10F32044A3C60003C045 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F22044A3C60003C045 /* Assets.xcassets */; };
|
||||
33CC10F62044A3C60003C045 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 33CC10F42044A3C60003C045 /* MainMenu.xib */; };
|
||||
33CC11132044BFA00003C045 /* MainFlutterWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 33CC11122044BFA00003C045 /* MainFlutterWindow.swift */; };
|
||||
54F28C357B28F7E8B9C54F84 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 10E57424BF8C84273089B76A /* Pods_Runner.framework */; };
|
||||
77D682650D9F71EDEC2BBD61 /* Pods_RunnerTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 980E05123DAD5E6061E174B5 /* Pods_RunnerTests.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
@@ -60,11 +62,15 @@
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0538F3A3A6CA382BFFC9379E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
055C5F79911D55B8019A5AC3 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
|
||||
084566EDC0549A51CCDF2E44 /* Pods-RunnerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.debug.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
10E57424BF8C84273089B76A /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
331C80D5294CF71000263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
331C80D7294CF71000263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
|
||||
333000ED22D3DE5D00554162 /* Warnings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Warnings.xcconfig; sourceTree = "<group>"; };
|
||||
335BBD1A22A9A15E00E9071D /* GeneratedPluginRegistrant.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneratedPluginRegistrant.swift; sourceTree = "<group>"; };
|
||||
33CC10ED2044A3C60003C045 /* flame_flip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "flame_flip.app"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10ED2044A3C60003C045 /* flame_flip.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = flame_flip.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
33CC10F02044A3C60003C045 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
|
||||
33CC10F22044A3C60003C045 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = Runner/Assets.xcassets; sourceTree = "<group>"; };
|
||||
33CC10F52044A3C60003C045 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
|
||||
@@ -76,8 +82,12 @@
|
||||
33E51913231747F40026EE4D /* DebugProfile.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DebugProfile.entitlements; sourceTree = "<group>"; };
|
||||
33E51914231749380026EE4D /* Release.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Release.entitlements; sourceTree = "<group>"; };
|
||||
33E5194F232828860026EE4D /* AppInfo.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = AppInfo.xcconfig; sourceTree = "<group>"; };
|
||||
55A7832EB7A49B5E3074B9FC /* Pods-RunnerTests.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.profile.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.profile.xcconfig"; sourceTree = "<group>"; };
|
||||
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Release.xcconfig; sourceTree = "<group>"; };
|
||||
87AC630F5BDC66AD3107859E /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
942EBDEBB7C5FD7BF1084AE2 /* Pods-RunnerTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-RunnerTests.release.xcconfig"; path = "Target Support Files/Pods-RunnerTests/Pods-RunnerTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; path = Debug.xcconfig; sourceTree = "<group>"; };
|
||||
980E05123DAD5E6061E174B5 /* Pods_RunnerTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_RunnerTests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@@ -85,6 +95,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
77D682650D9F71EDEC2BBD61 /* Pods_RunnerTests.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -92,6 +103,7 @@
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
54F28C357B28F7E8B9C54F84 /* Pods_Runner.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
@@ -125,6 +137,7 @@
|
||||
331C80D6294CF71000263BE5 /* RunnerTests */,
|
||||
33CC10EE2044A3C60003C045 /* Products */,
|
||||
D73912EC22F37F3D000D13A0 /* Frameworks */,
|
||||
BC9EAA4A38B1568738EF72DF /* Pods */,
|
||||
);
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
@@ -172,9 +185,25 @@
|
||||
path = Runner;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
BC9EAA4A38B1568738EF72DF /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
87AC630F5BDC66AD3107859E /* Pods-Runner.debug.xcconfig */,
|
||||
055C5F79911D55B8019A5AC3 /* Pods-Runner.release.xcconfig */,
|
||||
0538F3A3A6CA382BFFC9379E /* Pods-Runner.profile.xcconfig */,
|
||||
084566EDC0549A51CCDF2E44 /* Pods-RunnerTests.debug.xcconfig */,
|
||||
942EBDEBB7C5FD7BF1084AE2 /* Pods-RunnerTests.release.xcconfig */,
|
||||
55A7832EB7A49B5E3074B9FC /* Pods-RunnerTests.profile.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
path = Pods;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
D73912EC22F37F3D000D13A0 /* Frameworks */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
10E57424BF8C84273089B76A /* Pods_Runner.framework */,
|
||||
980E05123DAD5E6061E174B5 /* Pods_RunnerTests.framework */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
@@ -186,6 +215,7 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 331C80DE294CF71000263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
|
||||
buildPhases = (
|
||||
590038735CF1A5055894D7E4 /* [CP] Check Pods Manifest.lock */,
|
||||
331C80D1294CF70F00263BE5 /* Sources */,
|
||||
331C80D2294CF70F00263BE5 /* Frameworks */,
|
||||
331C80D3294CF70F00263BE5 /* Resources */,
|
||||
@@ -204,11 +234,13 @@
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 33CC10FB2044A3C60003C045 /* Build configuration list for PBXNativeTarget "Runner" */;
|
||||
buildPhases = (
|
||||
519A294386667F56A9CCEC43 /* [CP] Check Pods Manifest.lock */,
|
||||
33CC10E92044A3C60003C045 /* Sources */,
|
||||
33CC10EA2044A3C60003C045 /* Frameworks */,
|
||||
33CC10EB2044A3C60003C045 /* Resources */,
|
||||
33CC110E2044A8840003C045 /* Bundle Framework */,
|
||||
3399D490228B24CF009A79C7 /* ShellScript */,
|
||||
5BF428EA9E8600924F5C3D16 /* [CP] Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
@@ -329,6 +361,67 @@
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"$FLUTTER_ROOT\"/packages/flutter_tools/bin/macos_assemble.sh && touch Flutter/ephemeral/tripwire";
|
||||
};
|
||||
519A294386667F56A9CCEC43 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
590038735CF1A5055894D7E4 /* [CP] Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
);
|
||||
inputPaths = (
|
||||
"${PODS_PODFILE_DIR_PATH}/Podfile.lock",
|
||||
"${PODS_ROOT}/Manifest.lock",
|
||||
);
|
||||
name = "[CP] Check Pods Manifest.lock";
|
||||
outputFileListPaths = (
|
||||
);
|
||||
outputPaths = (
|
||||
"$(DERIVED_FILE_DIR)/Pods-RunnerTests-checkManifestLockResult.txt",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
5BF428EA9E8600924F5C3D16 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
/* End PBXShellScriptBuildPhase section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
@@ -380,6 +473,7 @@
|
||||
/* Begin XCBuildConfiguration section */
|
||||
331C80DB294CF71000263BE5 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 084566EDC0549A51CCDF2E44 /* Pods-RunnerTests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -394,6 +488,7 @@
|
||||
};
|
||||
331C80DC294CF71000263BE5 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 942EBDEBB7C5FD7BF1084AE2 /* Pods-RunnerTests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
@@ -408,6 +503,7 @@
|
||||
};
|
||||
331C80DD294CF71000263BE5 /* Profile */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 55A7832EB7A49B5E3074B9FC /* Pods-RunnerTests.profile.xcconfig */;
|
||||
buildSettings = {
|
||||
BUNDLE_LOADER = "$(TEST_HOST)";
|
||||
CURRENT_PROJECT_VERSION = 1;
|
||||
|
||||
@@ -4,4 +4,7 @@
|
||||
<FileRef
|
||||
location = "group:Runner.xcodeproj">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
</Workspace>
|
||||
|
||||
348
pubspec.lock
@@ -5,32 +5,48 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: adjust_sdk
|
||||
sha256: "62408962d8b01e0631f4d83ca7300fa43ea7d3b95ad9784fe7a8477e016987e1"
|
||||
url: "https://pub.dev"
|
||||
sha256: "5bd20ab37263d41c7b3e2016dd09a70e5f828051c71cec37bf19d91538c95641"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.5.1"
|
||||
version: "5.6.2"
|
||||
android_id:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: android_id
|
||||
sha256: "50d62501d623a7e7358b3ceffd1bdd9b420292eba66cec8347d33ed10791f28e"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.5.1"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
sha256: d0481093c50b1da8910eb0bb301626d4d8eb7284aa739614d2b394ee09e3ea04
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.7.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
|
||||
url: "https://pub.dev"
|
||||
sha256: e2eb0491ba5ddb6177742d2da23904574082139b07c1e33b8503b9f46f3e1a37
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.13.0"
|
||||
version: "2.13.1"
|
||||
audioplayers:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: audioplayers
|
||||
sha256: a72dd459d1a48f61a6fb9c0134dba26597c9236af40639ff0eb70eb4e0baab70
|
||||
url: "https://pub.dev"
|
||||
sha256: f16640453cc47487b7de72a2b28d37c7df1ac97999849f4a46d92b1d2b0f093d
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.6.0"
|
||||
version: "6.7.1"
|
||||
audioplayers_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_android
|
||||
sha256: "60a6728277228413a85755bd3ffd6fab98f6555608923813ce383b190a360605"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.1"
|
||||
audioplayers_darwin:
|
||||
@@ -38,7 +54,7 @@ packages:
|
||||
description:
|
||||
name: audioplayers_darwin
|
||||
sha256: c994b3bb3a921e4904ac40e013fbc94488e824fd7c1de6326f549943b0b44a91
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.4.0"
|
||||
audioplayers_linux:
|
||||
@@ -46,7 +62,7 @@ packages:
|
||||
description:
|
||||
name: audioplayers_linux
|
||||
sha256: f75bce1ce864170ef5e6a2c6a61cd3339e1a17ce11e99a25bae4474ea491d001
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.2.1"
|
||||
audioplayers_platform_interface:
|
||||
@@ -54,31 +70,31 @@ packages:
|
||||
description:
|
||||
name: audioplayers_platform_interface
|
||||
sha256: "0e2f6a919ab56d0fec272e801abc07b26ae7f31980f912f24af4748763e5a656"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "7.1.1"
|
||||
audioplayers_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_web
|
||||
sha256: faa8fa6587f996a6f604433b53af44c57a1407d4fe8dff5766cf63d6875e8de9
|
||||
url: "https://pub.dev"
|
||||
sha256: "24a6f258062bd7da8cb2157e83fccb9816a08dd306cbaaa24f9813d071470545"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "5.2.1"
|
||||
audioplayers_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: audioplayers_windows
|
||||
sha256: bafff2b38b6f6d331887558ba6e0a01c9c208d9dbb3ad0005234db065122a734
|
||||
url: "https://pub.dev"
|
||||
sha256: "95f875a96c88c3dbbcb608d4f8288e300b0113d256a81d0b3197fcc18f0dc91a"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.3.0"
|
||||
version: "4.3.1"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
characters:
|
||||
@@ -86,7 +102,7 @@ packages:
|
||||
description:
|
||||
name: characters
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
clock:
|
||||
@@ -94,23 +110,23 @@ packages:
|
||||
description:
|
||||
name: clock
|
||||
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
code_assets:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_assets
|
||||
sha256: "83ccdaa064c980b5596c35dd64a8d3ecc68620174ab9b90b6343b753aa721687"
|
||||
url: "https://pub.dev"
|
||||
sha256: bf394f466ba9205f1812a0433b392d6af280f155f56651eda7c18cc32ed493b8
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
version: "1.2.1"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.19.1"
|
||||
convert:
|
||||
@@ -118,7 +134,7 @@ packages:
|
||||
description:
|
||||
name: convert
|
||||
sha256: b30acd5944035672bc15c6b7a8b47d773e41e2f17de064350988c5d02adb1c68
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
crypto:
|
||||
@@ -126,31 +142,31 @@ packages:
|
||||
description:
|
||||
name: crypto
|
||||
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.7"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
|
||||
url: "https://pub.dev"
|
||||
sha256: "41e005c33bd814be4d3096aff55b1908d419fde52ca656c8c47719ec745873cd"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.8"
|
||||
version: "1.0.9"
|
||||
device_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: device_info_plus
|
||||
sha256: "4df8babf73058181227e18b08e6ea3520cf5fc5d796888d33b7cb0f33f984b7c"
|
||||
url: "https://pub.dev"
|
||||
sha256: b4fed1b2835da9d670d7bed7db79ae2a94b0f5ad6312268158a9b5479abbacdd
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "12.3.0"
|
||||
version: "12.4.0"
|
||||
device_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: device_info_plus_platform_interface
|
||||
sha256: e1ea89119e34903dca74b883d0dd78eb762814f97fb6c76f35e9ff74d261a18f
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "7.0.3"
|
||||
fake_async:
|
||||
@@ -158,7 +174,7 @@ packages:
|
||||
description:
|
||||
name: fake_async
|
||||
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.3"
|
||||
ffi:
|
||||
@@ -166,7 +182,7 @@ packages:
|
||||
description:
|
||||
name: ffi
|
||||
sha256: "6d7fd89431262d8f3125e81b50d3847a091d846eafcd4fdb88dd06f36d705a45"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
file:
|
||||
@@ -174,7 +190,7 @@ packages:
|
||||
description:
|
||||
name: file
|
||||
sha256: a3b4f84adafef897088c160faf7dfffb7696046cb13ae90b508c2cbc95d3b8d4
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "7.0.1"
|
||||
fixnum:
|
||||
@@ -182,17 +198,17 @@ packages:
|
||||
description:
|
||||
name: fixnum
|
||||
sha256: b6dc7065e46c974bc7c5f143080a6764ec7a4be6da1285ececdc37be96de53be
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
flame:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flame
|
||||
sha256: "78c87c34d512f5dd5b69bda823bf31a9f53b27cf319b5326b788f0ec93cbd0b3"
|
||||
url: "https://pub.dev"
|
||||
sha256: b9e65f6d7d06a301d6ea3cde03731cad3cdc255d56e0fb53c56c1e7806aaaf6a
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.36.0"
|
||||
version: "1.37.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@@ -203,7 +219,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview
|
||||
sha256: "80092d13d3e29b6227e25b67973c67c7210bd5e35c4b747ca908e31eb71a46d5"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.1.5"
|
||||
flutter_inappwebview_android:
|
||||
@@ -211,7 +227,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_android
|
||||
sha256: "62557c15a5c2db5d195cb3892aab74fcaec266d7b86d59a6f0027abd672cddba"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
flutter_inappwebview_internal_annotations:
|
||||
@@ -219,7 +235,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_internal_annotations
|
||||
sha256: e30fba942e3debea7b7e6cdd4f0f59ce89dd403a9865193e3221293b6d1544c6
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
flutter_inappwebview_ios:
|
||||
@@ -227,7 +243,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_ios
|
||||
sha256: "5818cf9b26cf0cbb0f62ff50772217d41ea8d3d9cc00279c45f8aabaa1b4025d"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
flutter_inappwebview_macos:
|
||||
@@ -235,7 +251,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_macos
|
||||
sha256: c1fbb86af1a3738e3541364d7d1866315ffb0468a1a77e34198c9be571287da1
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
flutter_inappwebview_platform_interface:
|
||||
@@ -243,7 +259,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_platform_interface
|
||||
sha256: cf5323e194096b6ede7a1ca808c3e0a078e4b33cc3f6338977d75b4024ba2500
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.0+1"
|
||||
flutter_inappwebview_web:
|
||||
@@ -251,7 +267,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_web
|
||||
sha256: "55f89c83b0a0d3b7893306b3bb545ba4770a4df018204917148ebb42dc14a598"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.2"
|
||||
flutter_inappwebview_windows:
|
||||
@@ -259,7 +275,7 @@ packages:
|
||||
description:
|
||||
name: flutter_inappwebview_windows
|
||||
sha256: "8b4d3a46078a2cdc636c4a3d10d10f2a16882f6be607962dbfff8874d1642055"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
flutter_lints:
|
||||
@@ -267,7 +283,7 @@ packages:
|
||||
description:
|
||||
name: flutter_lints
|
||||
sha256: "3105dc8492f6183fb076ccf1f351ac3d60564bff92e20bfc4af9cc1651f4e7e1"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.0.0"
|
||||
flutter_test:
|
||||
@@ -275,33 +291,33 @@ packages:
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_vpn_detector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_vpn_detector
|
||||
sha256: f68a476df2aa6539f65f549c17a19e1bd210f78ff9e0345468c0575b67c1f746
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
flutter_web_plugins:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
glob:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: glob
|
||||
sha256: c3f1ee72c96f8f78935e18aa8cecced9ab132419e8625dc187e1c2408efc20de
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
hooks:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: hooks
|
||||
sha256: e79ed1e8e1929bc6ecb6ec85f0cb519c887aa5b423705ded0d0f2d9226def388
|
||||
url: "https://pub.dev"
|
||||
sha256: "9a62a50b50b769a737bc0a8ff381f333529df3ab746b2f6b02e83760231455ba"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "2.0.2"
|
||||
http:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: http
|
||||
sha256: "87721a4a50b19c7f1d49001e51409bddc46303966ce89a65af4f4e6004896412"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
http_parser:
|
||||
@@ -309,15 +325,31 @@ packages:
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
jni:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: jni
|
||||
sha256: c2230682d5bc2362c1c9e8d3c7f406d9cbba23ab3f2e203a025dd47e0fb2e68f
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
jni_flutter:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: jni_flutter
|
||||
sha256: "8b59e590786050b1cd866677dddaf76b1ade5e7bc751abe04b86e84d379d3ba6"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.1"
|
||||
leak_tracker:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: leak_tracker
|
||||
sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "11.0.2"
|
||||
leak_tracker_flutter_testing:
|
||||
@@ -325,7 +357,7 @@ packages:
|
||||
description:
|
||||
name: leak_tracker_flutter_testing
|
||||
sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.10"
|
||||
leak_tracker_testing:
|
||||
@@ -333,7 +365,7 @@ packages:
|
||||
description:
|
||||
name: leak_tracker_testing
|
||||
sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.2"
|
||||
lints:
|
||||
@@ -341,7 +373,7 @@ packages:
|
||||
description:
|
||||
name: lints
|
||||
sha256: "12f842a479589fea194fe5c5a3095abc7be0c1f2ddfa9a0e76aed1dbd26a87df"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.1.0"
|
||||
logging:
|
||||
@@ -349,7 +381,7 @@ packages:
|
||||
description:
|
||||
name: logging
|
||||
sha256: c8245ada5f1717ed44271ed1c26b8ce85ca3228fd2ffdb75468ab01979309d61
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
matcher:
|
||||
@@ -357,7 +389,7 @@ packages:
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.12.19"
|
||||
material_color_utilities:
|
||||
@@ -365,55 +397,55 @@ packages:
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: "23f08335362185a5ea2ad3a4e597f1375e78bce8a040df5c600c8d3552ef2394"
|
||||
url: "https://pub.dev"
|
||||
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.17.0"
|
||||
native_toolchain_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: native_toolchain_c
|
||||
sha256: "92b2ca62c8bd2b8d2f267cdfccf9bfbdb7322f778f8f91b3ce5b5cda23a3899f"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.17.5"
|
||||
version: "1.18.0"
|
||||
objective_c:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: objective_c
|
||||
sha256: "100a1c87616ab6ed41ec263b083c0ef3261ee6cd1dc3b0f35f8ddfa4f996fe52"
|
||||
url: "https://pub.dev"
|
||||
sha256: "6cb691c686fa2838c6deb34980d426145c2a5d537491cb83d463c33cdbc726ed"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "9.3.0"
|
||||
version: "9.4.1"
|
||||
ordered_set:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ordered_set
|
||||
sha256: d6c1d053a533e84931a388cbf03f1ad21a0543bf06c7a281859d3ffacd8e15f2
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "8.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
sha256: f096c55ebb7deb7e384101542bfba8c52696c1b56fca2eb62827989ef2353bbc
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
package_info_plus:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: package_info_plus
|
||||
sha256: f69da0d3189a4b4ceaeb1a3defb0f329b3b352517f52bed4290f83d4f06bc08d
|
||||
url: "https://pub.dev"
|
||||
sha256: "468c26b4254ab01979fa5e4a98cb343ea3631b9acee6f21028997419a80e1a20"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "9.0.0"
|
||||
version: "9.0.1"
|
||||
package_info_plus_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_info_plus_platform_interface
|
||||
sha256: "202a487f08836a592a6bd4f901ac69b3a8f146af552bbd14407b6b41e1c3f086"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.2.1"
|
||||
path:
|
||||
@@ -421,7 +453,7 @@ packages:
|
||||
description:
|
||||
name: path
|
||||
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.1"
|
||||
path_provider:
|
||||
@@ -429,23 +461,23 @@ packages:
|
||||
description:
|
||||
name: path_provider
|
||||
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.5"
|
||||
path_provider_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_android
|
||||
sha256: f2c65e21139ce2c3dad46922be8272bb5963516045659e71bb16e151c93b580e
|
||||
url: "https://pub.dev"
|
||||
sha256: "69cbd515a62b94d32a7944f086b2f82b4ac40a1d45bebfc00813a430ab2dabcd"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.22"
|
||||
version: "2.3.1"
|
||||
path_provider_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_foundation
|
||||
sha256: "2a376b7d6392d80cd3705782d2caa734ca4727776db0b6ec36ef3f1855197699"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.6.0"
|
||||
path_provider_linux:
|
||||
@@ -453,7 +485,7 @@ packages:
|
||||
description:
|
||||
name: path_provider_linux
|
||||
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
path_provider_platform_interface:
|
||||
@@ -461,7 +493,7 @@ packages:
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.2"
|
||||
path_provider_windows:
|
||||
@@ -469,7 +501,7 @@ packages:
|
||||
description:
|
||||
name: path_provider_windows
|
||||
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.3.0"
|
||||
platform:
|
||||
@@ -477,7 +509,7 @@ packages:
|
||||
description:
|
||||
name: platform
|
||||
sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.6"
|
||||
play_install_referrer:
|
||||
@@ -485,7 +517,7 @@ packages:
|
||||
description:
|
||||
name: play_install_referrer
|
||||
sha256: "7dd808236d35d15199d5e7a5b55488e4343c1b67c4694902d6b95196b22b19cd"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
plugin_platform_interface:
|
||||
@@ -493,7 +525,7 @@ packages:
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.8"
|
||||
pointycastle:
|
||||
@@ -501,7 +533,7 @@ packages:
|
||||
description:
|
||||
name: pointycastle
|
||||
sha256: "92aa3841d083cc4b0f4709b5c74fd6409a3e6ba833ffc7dc6a8fee096366acf5"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
pub_semver:
|
||||
@@ -509,31 +541,39 @@ packages:
|
||||
description:
|
||||
name: pub_semver
|
||||
sha256: "5bfcf68ca79ef689f8990d1160781b4bad40a3bd5e5218ad4076ddb7f4081585"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
record_use:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: record_use
|
||||
sha256: "2551bd8eecfe95d14ae75f6021ad0248be5c27f138c2ec12fcb52b500b3ba1ed"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
shared_preferences:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: shared_preferences
|
||||
sha256: "2939ae520c9024cb197fc20dee269cd8cdbf564c8b5746374ec6cacdc5169e64"
|
||||
url: "https://pub.dev"
|
||||
sha256: c3025c5534b01739267eb7d76959bbc25a6d10f6988e1c2a3036940133dd10bf
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.5.4"
|
||||
version: "2.5.5"
|
||||
shared_preferences_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_android
|
||||
sha256: "8374d6200ab33ac99031a852eba4c8eb2170c4bf20778b3e2c9eccb45384fb41"
|
||||
url: "https://pub.dev"
|
||||
sha256: a2c49fc1fed7140cadd892d765bd47edbe4ac0b9c7e7e3c493dcb58126f99cf0
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.21"
|
||||
version: "2.4.25"
|
||||
shared_preferences_foundation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_foundation
|
||||
sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.5.6"
|
||||
shared_preferences_linux:
|
||||
@@ -541,23 +581,23 @@ packages:
|
||||
description:
|
||||
name: shared_preferences_linux
|
||||
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
shared_preferences_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_platform_interface
|
||||
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
|
||||
url: "https://pub.dev"
|
||||
sha256: "649dc798a33931919ea356c4305c2d1f81619ea6e92244070b520187b5140ef9"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.4.2"
|
||||
shared_preferences_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shared_preferences_web
|
||||
sha256: c49bd060261c9a3f0ff445892695d6212ff603ef3115edbb448509d407600019
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.3"
|
||||
shared_preferences_windows:
|
||||
@@ -565,7 +605,7 @@ packages:
|
||||
description:
|
||||
name: shared_preferences_windows
|
||||
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
sky_engine:
|
||||
@@ -578,7 +618,7 @@ packages:
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "56a02f1f4cd1a2d96303c0144c93bd6d909eea6bee6bf5a0e0b685edbd4c47ab"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.10.2"
|
||||
stack_trace:
|
||||
@@ -586,7 +626,7 @@ packages:
|
||||
description:
|
||||
name: stack_trace
|
||||
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.12.1"
|
||||
stream_channel:
|
||||
@@ -594,7 +634,7 @@ packages:
|
||||
description:
|
||||
name: stream_channel
|
||||
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
string_scanner:
|
||||
@@ -602,39 +642,39 @@ packages:
|
||||
description:
|
||||
name: string_scanner
|
||||
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.4.1"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
sha256: c254ade258ec8282947a0acbbc90b9575b4f19673533ee46f2f6e9b3aeefd7c0
|
||||
url: "https://pub.dev"
|
||||
sha256: "93b153dcb6a26dcddee6ca087dd634b53e38c10b5aa163e8e49501a776456153"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.4.0"
|
||||
version: "3.4.1"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.2"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "8161c84903fd860b26bfdefb7963b3f0b68fee7adea0f59ef805ecca346f0c7a"
|
||||
url: "https://pub.dev"
|
||||
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.7.10"
|
||||
version: "0.7.11"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
url_launcher:
|
||||
@@ -642,23 +682,23 @@ packages:
|
||||
description:
|
||||
name: url_launcher
|
||||
sha256: f6a7e5c4835bb4e3026a04793a4199ca2d14c739ec378fdfe23fc8075d0439f8
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.3.2"
|
||||
url_launcher_android:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: url_launcher_android
|
||||
sha256: "767344bf3063897b5cf0db830e94f904528e6dd50a6dfaf839f0abf509009611"
|
||||
url: "https://pub.dev"
|
||||
sha256: b413d49b73867ac08dd2f9890efd3cc11f2a0e577618d50843440a1fb3776c32
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.3.28"
|
||||
version: "6.3.32"
|
||||
url_launcher_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_ios
|
||||
sha256: "580fe5dfb51671ae38191d316e027f6b76272b026370708c2d898799750a02b0"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "6.4.1"
|
||||
url_launcher_linux:
|
||||
@@ -666,7 +706,7 @@ packages:
|
||||
description:
|
||||
name: url_launcher_linux
|
||||
sha256: d5e14138b3bc193a0f63c10a53c94b91d399df0512b1f29b94a043db7482384a
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.2.2"
|
||||
url_launcher_macos:
|
||||
@@ -674,7 +714,7 @@ packages:
|
||||
description:
|
||||
name: url_launcher_macos
|
||||
sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.2.5"
|
||||
url_launcher_platform_interface:
|
||||
@@ -682,31 +722,31 @@ packages:
|
||||
description:
|
||||
name: url_launcher_platform_interface
|
||||
sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.3.2"
|
||||
url_launcher_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_web
|
||||
sha256: d0412fcf4c6b31ecfdb7762359b7206ffba3bbffd396c6d9f9c4616ece476c1f
|
||||
url: "https://pub.dev"
|
||||
sha256: "85c81589622fbc87c1c683aaea164d3604a7777495a79d91e39ffcdec39ddb34"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.2"
|
||||
version: "2.4.3"
|
||||
url_launcher_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: url_launcher_windows
|
||||
sha256: "712c70ab1b99744ff066053cbe3e80c73332b38d46e5e945c98689b2e66fc15f"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.5"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: uuid
|
||||
sha256: "1fef9e8e11e2991bb773070d4656b7bd5d850967a2456cfc83cf47925ba79489"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.5.3"
|
||||
vector_math:
|
||||
@@ -714,23 +754,23 @@ packages:
|
||||
description:
|
||||
name: vector_math
|
||||
sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
vm_service:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vm_service
|
||||
sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60"
|
||||
url: "https://pub.dev"
|
||||
sha256: "0016aef94fc66495ac78af5859181e3f3bf2026bd8eecc72b9565601e19ab360"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "15.0.2"
|
||||
version: "15.2.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
win32:
|
||||
@@ -738,7 +778,7 @@ packages:
|
||||
description:
|
||||
name: win32
|
||||
sha256: d7cb55e04cd34096cd3a79b3330245f54cb96a370a1c27adb3c84b917de8b08e
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.15.0"
|
||||
win32_registry:
|
||||
@@ -746,7 +786,7 @@ packages:
|
||||
description:
|
||||
name: win32_registry
|
||||
sha256: "6f1b564492d0147b330dd794fee8f512cec4977957f310f9951b5f9d83618dae"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.0"
|
||||
xdg_directories:
|
||||
@@ -754,7 +794,7 @@ packages:
|
||||
description:
|
||||
name: xdg_directories
|
||||
sha256: "7a3f37b05d989967cdddcbb571f1ea834867ae2faa29725fd085180e0883aa15"
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
yaml:
|
||||
@@ -762,9 +802,9 @@ packages:
|
||||
description:
|
||||
name: yaml
|
||||
sha256: b9da305ac7c39faa3f030eccd175340f968459dae4af175130b3fc47e40d76ce
|
||||
url: "https://pub.dev"
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.11.1 <4.0.0"
|
||||
flutter: ">=3.41.0"
|
||||
dart: ">=3.12.0 <4.0.0"
|
||||
flutter: ">=3.44.0"
|
||||
|
||||
@@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
||||
# In Windows, build-name is used as the major, minor, and patch parts
|
||||
# of the product and file versions while build-number is used as the build suffix.
|
||||
version: 1.0.2+4
|
||||
version: 1.0.0+0
|
||||
|
||||
environment:
|
||||
sdk: ^3.11.1
|
||||
@@ -43,6 +43,9 @@ dependencies:
|
||||
package_info_plus: ^9.0.0
|
||||
device_info_plus: ^12.3.0
|
||||
flame: ^1.36.0
|
||||
android_id: ^0.5.1
|
||||
uuid: ^4.5.3
|
||||
flutter_vpn_detector: ^0.1.5
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
#include <audioplayers_windows/audioplayers_windows_plugin.h>
|
||||
#include <flutter_inappwebview_windows/flutter_inappwebview_windows_plugin_c_api.h>
|
||||
#include <flutter_vpn_detector/flutter_vpn_detector_plugin.h>
|
||||
#include <url_launcher_windows/url_launcher_windows.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
@@ -15,6 +16,8 @@ void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
registry->GetRegistrarForPlugin("AudioplayersWindowsPlugin"));
|
||||
FlutterInappwebviewWindowsPluginCApiRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterInappwebviewWindowsPluginCApi"));
|
||||
FlutterVpnDetectorPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterVpnDetectorPlugin"));
|
||||
UrlLauncherWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("UrlLauncherWindows"));
|
||||
}
|
||||
|
||||
@@ -5,10 +5,12 @@
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
audioplayers_windows
|
||||
flutter_inappwebview_windows
|
||||
flutter_vpn_detector
|
||||
url_launcher_windows
|
||||
)
|
||||
|
||||
list(APPEND FLUTTER_FFI_PLUGIN_LIST
|
||||
jni
|
||||
)
|
||||
|
||||
set(PLUGIN_BUNDLED_LIBRARIES)
|
||||
|
||||