├── .gitignore ├── ChatGKD.xcodeproj ├── project.pbxproj └── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ ├── IDEWorkspaceChecks.plist │ └── swiftpm │ └── Package.resolved ├── ChatGKD ├── Assets.xcassets │ ├── AccentColor.colorset │ │ └── Contents.json │ ├── AppIcon.appiconset │ │ ├── Contents.json │ │ └── chatgkd-icon.png │ └── Contents.json ├── ChatGKD.xcdatamodeld │ ├── .xccurrentversion │ └── ChatGKD.xcdatamodel │ │ └── contents ├── ChatGKDApp.swift ├── ChatListView.swift ├── ContentView.swift ├── HistoryChatView.swift ├── MainView.swift ├── Model │ └── ChatModel.swift ├── Persistence.swift ├── Preview Content │ └── Preview Assets.xcassets │ │ └── Contents.json ├── SettingsView.swift └── Utils │ ├── ChatGPTHelper.swift │ └── ChatProvider.swift ├── README.md ├── assets ├── index-47f8a1c6.js └── index-c837ffa6.css ├── index.html ├── manifest.webmanifest ├── registerSW.js ├── resources ├── chatgkd-icon.png ├── history.PNG ├── main.PNG └── web.jpeg ├── sw.js ├── web ├── .eslintrc.cjs ├── .gitignore ├── .prettierrc.json ├── .vscode │ └── extensions.json ├── README.md ├── assets │ ├── index-452cecbb.js │ └── index-f97c6ee6.css ├── env.d.ts ├── index.html ├── package-lock.json ├── package.json ├── src │ ├── App.vue │ ├── AppState.ts │ ├── ChatGPTAPI.ts │ ├── OpenAIChatAPI.ts │ ├── assets │ │ └── main.css │ └── main.ts ├── tsconfig.config.json ├── tsconfig.json └── vite.config.ts └── workbox-7369c0e1.js /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## User settings 6 | xcuserdata/ 7 | 8 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9) 9 | *.xcscmblueprint 10 | *.xccheckout 11 | 12 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4) 13 | build/ 14 | DerivedData/ 15 | *.moved-aside 16 | *.pbxuser 17 | !default.pbxuser 18 | *.mode1v3 19 | !default.mode1v3 20 | *.mode2v3 21 | !default.mode2v3 22 | *.perspectivev3 23 | !default.perspectivev3 24 | 25 | ## Obj-C/Swift specific 26 | *.hmap 27 | 28 | ## App packaging 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | # Package.pins 42 | # Package.resolved 43 | # *.xcodeproj 44 | # 45 | # Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata 46 | # hence it is not needed unless you have added a package configuration file to your project 47 | # .swiftpm 48 | 49 | .build/ 50 | 51 | # CocoaPods 52 | # 53 | # We recommend against adding the Pods directory to your .gitignore. However 54 | # you should judge for yourself, the pros and cons are mentioned at: 55 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 56 | # 57 | # Pods/ 58 | # 59 | # Add this line if you want to avoid checking in source code from the Xcode workspace 60 | # *.xcworkspace 61 | 62 | # Carthage 63 | # 64 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 65 | # Carthage/Checkouts 66 | 67 | Carthage/Build/ 68 | 69 | # Accio dependency management 70 | Dependencies/ 71 | .accio/ 72 | 73 | # fastlane 74 | # 75 | # It is recommended to not store the screenshots in the git repo. 76 | # Instead, use fastlane to re-generate the screenshots whenever they are needed. 77 | # For more information about the recommended setup visit: 78 | # https://docs.fastlane.tools/best-practices/source-control/#source-control 79 | 80 | fastlane/report.xml 81 | fastlane/Preview.html 82 | fastlane/screenshots/**/*.png 83 | fastlane/test_output 84 | 85 | # Code Injection 86 | # 87 | # After new code Injection tools there's a generated folder /iOSInjectionProject 88 | # https://github.com/johnno1962/injectionforxcode 89 | 90 | iOSInjectionProject/ 91 | 92 | .DS_Store 93 | -------------------------------------------------------------------------------- /ChatGKD.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 56; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 843F60A4299A84900079886F /* ChatGKDApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60A3299A84900079886F /* ChatGKDApp.swift */; }; 11 | 843F60A6299A84900079886F /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60A5299A84900079886F /* ContentView.swift */; }; 12 | 843F60A8299A84910079886F /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 843F60A7299A84910079886F /* Assets.xcassets */; }; 13 | 843F60AB299A84910079886F /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 843F60AA299A84910079886F /* Preview Assets.xcassets */; }; 14 | 843F60AD299A84910079886F /* Persistence.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60AC299A84910079886F /* Persistence.swift */; }; 15 | 843F60B0299A84910079886F /* ChatGKD.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 843F60AE299A84910079886F /* ChatGKD.xcdatamodeld */; }; 16 | 843F60B7299A85AD0079886F /* MainView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60B6299A85AD0079886F /* MainView.swift */; }; 17 | 843F60B9299A86720079886F /* ChatListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60B8299A86720079886F /* ChatListView.swift */; }; 18 | 843F60BB299A86C40079886F /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60BA299A86C40079886F /* SettingsView.swift */; }; 19 | 843F60C3299A8C630079886F /* ChatProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60C2299A8C630079886F /* ChatProvider.swift */; }; 20 | 843F60C6299A8F650079886F /* ChatGPTSwift in Frameworks */ = {isa = PBXBuildFile; productRef = 843F60C5299A8F650079886F /* ChatGPTSwift */; }; 21 | 843F60C8299A8FC80079886F /* ChatGPTHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60C7299A8FC80079886F /* ChatGPTHelper.swift */; }; 22 | 843F60CB299A950B0079886F /* ChatModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60CA299A950B0079886F /* ChatModel.swift */; }; 23 | 843F60CD299AA6EC0079886F /* HistoryChatView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 843F60CC299AA6EC0079886F /* HistoryChatView.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXFileReference section */ 27 | 843F60A0299A84900079886F /* ChatGKD.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ChatGKD.app; sourceTree = BUILT_PRODUCTS_DIR; }; 28 | 843F60A3299A84900079886F /* ChatGKDApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatGKDApp.swift; sourceTree = ""; }; 29 | 843F60A5299A84900079886F /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; 30 | 843F60A7299A84910079886F /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 31 | 843F60AA299A84910079886F /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; 32 | 843F60AC299A84910079886F /* Persistence.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Persistence.swift; sourceTree = ""; }; 33 | 843F60AF299A84910079886F /* ChatGKD.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = ChatGKD.xcdatamodel; sourceTree = ""; }; 34 | 843F60B6299A85AD0079886F /* MainView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainView.swift; sourceTree = ""; }; 35 | 843F60B8299A86720079886F /* ChatListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatListView.swift; sourceTree = ""; }; 36 | 843F60BA299A86C40079886F /* SettingsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsView.swift; sourceTree = ""; }; 37 | 843F60C2299A8C630079886F /* ChatProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatProvider.swift; sourceTree = ""; }; 38 | 843F60C7299A8FC80079886F /* ChatGPTHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatGPTHelper.swift; sourceTree = ""; }; 39 | 843F60CA299A950B0079886F /* ChatModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ChatModel.swift; sourceTree = ""; }; 40 | 843F60CC299AA6EC0079886F /* HistoryChatView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HistoryChatView.swift; sourceTree = ""; }; 41 | /* End PBXFileReference section */ 42 | 43 | /* Begin PBXFrameworksBuildPhase section */ 44 | 843F609D299A84900079886F /* Frameworks */ = { 45 | isa = PBXFrameworksBuildPhase; 46 | buildActionMask = 2147483647; 47 | files = ( 48 | 843F60C6299A8F650079886F /* ChatGPTSwift in Frameworks */, 49 | ); 50 | runOnlyForDeploymentPostprocessing = 0; 51 | }; 52 | /* End PBXFrameworksBuildPhase section */ 53 | 54 | /* Begin PBXGroup section */ 55 | 843F6097299A84900079886F = { 56 | isa = PBXGroup; 57 | children = ( 58 | 843F60A2299A84900079886F /* ChatGKD */, 59 | 843F60A1299A84900079886F /* Products */, 60 | ); 61 | sourceTree = ""; 62 | }; 63 | 843F60A1299A84900079886F /* Products */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 843F60A0299A84900079886F /* ChatGKD.app */, 67 | ); 68 | name = Products; 69 | sourceTree = ""; 70 | }; 71 | 843F60A2299A84900079886F /* ChatGKD */ = { 72 | isa = PBXGroup; 73 | children = ( 74 | 843F60C9299A95040079886F /* Model */, 75 | 843F60BF299A8C460079886F /* Utils */, 76 | 843F60A3299A84900079886F /* ChatGKDApp.swift */, 77 | 843F60A5299A84900079886F /* ContentView.swift */, 78 | 843F60A7299A84910079886F /* Assets.xcassets */, 79 | 843F60AC299A84910079886F /* Persistence.swift */, 80 | 843F60AE299A84910079886F /* ChatGKD.xcdatamodeld */, 81 | 843F60A9299A84910079886F /* Preview Content */, 82 | 843F60B6299A85AD0079886F /* MainView.swift */, 83 | 843F60B8299A86720079886F /* ChatListView.swift */, 84 | 843F60BA299A86C40079886F /* SettingsView.swift */, 85 | 843F60CC299AA6EC0079886F /* HistoryChatView.swift */, 86 | ); 87 | path = ChatGKD; 88 | sourceTree = ""; 89 | }; 90 | 843F60A9299A84910079886F /* Preview Content */ = { 91 | isa = PBXGroup; 92 | children = ( 93 | 843F60AA299A84910079886F /* Preview Assets.xcassets */, 94 | ); 95 | path = "Preview Content"; 96 | sourceTree = ""; 97 | }; 98 | 843F60BF299A8C460079886F /* Utils */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 843F60C2299A8C630079886F /* ChatProvider.swift */, 102 | 843F60C7299A8FC80079886F /* ChatGPTHelper.swift */, 103 | ); 104 | path = Utils; 105 | sourceTree = ""; 106 | }; 107 | 843F60C9299A95040079886F /* Model */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | 843F60CA299A950B0079886F /* ChatModel.swift */, 111 | ); 112 | path = Model; 113 | sourceTree = ""; 114 | }; 115 | /* End PBXGroup section */ 116 | 117 | /* Begin PBXNativeTarget section */ 118 | 843F609F299A84900079886F /* ChatGKD */ = { 119 | isa = PBXNativeTarget; 120 | buildConfigurationList = 843F60B3299A84910079886F /* Build configuration list for PBXNativeTarget "ChatGKD" */; 121 | buildPhases = ( 122 | 843F609C299A84900079886F /* Sources */, 123 | 843F609D299A84900079886F /* Frameworks */, 124 | 843F609E299A84900079886F /* Resources */, 125 | ); 126 | buildRules = ( 127 | ); 128 | dependencies = ( 129 | ); 130 | name = ChatGKD; 131 | packageProductDependencies = ( 132 | 843F60C5299A8F650079886F /* ChatGPTSwift */, 133 | ); 134 | productName = ChatGKD; 135 | productReference = 843F60A0299A84900079886F /* ChatGKD.app */; 136 | productType = "com.apple.product-type.application"; 137 | }; 138 | /* End PBXNativeTarget section */ 139 | 140 | /* Begin PBXProject section */ 141 | 843F6098299A84900079886F /* Project object */ = { 142 | isa = PBXProject; 143 | attributes = { 144 | BuildIndependentTargetsInParallel = 1; 145 | LastSwiftUpdateCheck = 1420; 146 | LastUpgradeCheck = 1420; 147 | TargetAttributes = { 148 | 843F609F299A84900079886F = { 149 | CreatedOnToolsVersion = 14.2; 150 | }; 151 | }; 152 | }; 153 | buildConfigurationList = 843F609B299A84900079886F /* Build configuration list for PBXProject "ChatGKD" */; 154 | compatibilityVersion = "Xcode 14.0"; 155 | developmentRegion = en; 156 | hasScannedForEncodings = 0; 157 | knownRegions = ( 158 | en, 159 | Base, 160 | ); 161 | mainGroup = 843F6097299A84900079886F; 162 | packageReferences = ( 163 | 843F60C4299A8F650079886F /* XCRemoteSwiftPackageReference "ChatGPTSwift" */, 164 | ); 165 | productRefGroup = 843F60A1299A84900079886F /* Products */; 166 | projectDirPath = ""; 167 | projectRoot = ""; 168 | targets = ( 169 | 843F609F299A84900079886F /* ChatGKD */, 170 | ); 171 | }; 172 | /* End PBXProject section */ 173 | 174 | /* Begin PBXResourcesBuildPhase section */ 175 | 843F609E299A84900079886F /* Resources */ = { 176 | isa = PBXResourcesBuildPhase; 177 | buildActionMask = 2147483647; 178 | files = ( 179 | 843F60AB299A84910079886F /* Preview Assets.xcassets in Resources */, 180 | 843F60A8299A84910079886F /* Assets.xcassets in Resources */, 181 | ); 182 | runOnlyForDeploymentPostprocessing = 0; 183 | }; 184 | /* End PBXResourcesBuildPhase section */ 185 | 186 | /* Begin PBXSourcesBuildPhase section */ 187 | 843F609C299A84900079886F /* Sources */ = { 188 | isa = PBXSourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 843F60BB299A86C40079886F /* SettingsView.swift in Sources */, 192 | 843F60AD299A84910079886F /* Persistence.swift in Sources */, 193 | 843F60A6299A84900079886F /* ContentView.swift in Sources */, 194 | 843F60C3299A8C630079886F /* ChatProvider.swift in Sources */, 195 | 843F60CD299AA6EC0079886F /* HistoryChatView.swift in Sources */, 196 | 843F60B0299A84910079886F /* ChatGKD.xcdatamodeld in Sources */, 197 | 843F60CB299A950B0079886F /* ChatModel.swift in Sources */, 198 | 843F60B7299A85AD0079886F /* MainView.swift in Sources */, 199 | 843F60B9299A86720079886F /* ChatListView.swift in Sources */, 200 | 843F60A4299A84900079886F /* ChatGKDApp.swift in Sources */, 201 | 843F60C8299A8FC80079886F /* ChatGPTHelper.swift in Sources */, 202 | ); 203 | runOnlyForDeploymentPostprocessing = 0; 204 | }; 205 | /* End PBXSourcesBuildPhase section */ 206 | 207 | /* Begin XCBuildConfiguration section */ 208 | 843F60B1299A84910079886F /* Debug */ = { 209 | isa = XCBuildConfiguration; 210 | buildSettings = { 211 | ALWAYS_SEARCH_USER_PATHS = NO; 212 | CLANG_ANALYZER_NONNULL = YES; 213 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 214 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 215 | CLANG_ENABLE_MODULES = YES; 216 | CLANG_ENABLE_OBJC_ARC = YES; 217 | CLANG_ENABLE_OBJC_WEAK = YES; 218 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 219 | CLANG_WARN_BOOL_CONVERSION = YES; 220 | CLANG_WARN_COMMA = YES; 221 | CLANG_WARN_CONSTANT_CONVERSION = YES; 222 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 223 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 224 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 225 | CLANG_WARN_EMPTY_BODY = YES; 226 | CLANG_WARN_ENUM_CONVERSION = YES; 227 | CLANG_WARN_INFINITE_RECURSION = YES; 228 | CLANG_WARN_INT_CONVERSION = YES; 229 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 230 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 231 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 232 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 233 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 234 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 235 | CLANG_WARN_STRICT_PROTOTYPES = YES; 236 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 237 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 238 | CLANG_WARN_UNREACHABLE_CODE = YES; 239 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 240 | COPY_PHASE_STRIP = NO; 241 | DEBUG_INFORMATION_FORMAT = dwarf; 242 | ENABLE_STRICT_OBJC_MSGSEND = YES; 243 | ENABLE_TESTABILITY = YES; 244 | GCC_C_LANGUAGE_STANDARD = gnu11; 245 | GCC_DYNAMIC_NO_PIC = NO; 246 | GCC_NO_COMMON_BLOCKS = YES; 247 | GCC_OPTIMIZATION_LEVEL = 0; 248 | GCC_PREPROCESSOR_DEFINITIONS = ( 249 | "DEBUG=1", 250 | "$(inherited)", 251 | ); 252 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 253 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 254 | GCC_WARN_UNDECLARED_SELECTOR = YES; 255 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 256 | GCC_WARN_UNUSED_FUNCTION = YES; 257 | GCC_WARN_UNUSED_VARIABLE = YES; 258 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 259 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; 260 | MTL_FAST_MATH = YES; 261 | ONLY_ACTIVE_ARCH = YES; 262 | SDKROOT = iphoneos; 263 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 264 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 265 | }; 266 | name = Debug; 267 | }; 268 | 843F60B2299A84910079886F /* Release */ = { 269 | isa = XCBuildConfiguration; 270 | buildSettings = { 271 | ALWAYS_SEARCH_USER_PATHS = NO; 272 | CLANG_ANALYZER_NONNULL = YES; 273 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; 274 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; 275 | CLANG_ENABLE_MODULES = YES; 276 | CLANG_ENABLE_OBJC_ARC = YES; 277 | CLANG_ENABLE_OBJC_WEAK = YES; 278 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 279 | CLANG_WARN_BOOL_CONVERSION = YES; 280 | CLANG_WARN_COMMA = YES; 281 | CLANG_WARN_CONSTANT_CONVERSION = YES; 282 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 283 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 284 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 285 | CLANG_WARN_EMPTY_BODY = YES; 286 | CLANG_WARN_ENUM_CONVERSION = YES; 287 | CLANG_WARN_INFINITE_RECURSION = YES; 288 | CLANG_WARN_INT_CONVERSION = YES; 289 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 290 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 291 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 292 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 293 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; 294 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 295 | CLANG_WARN_STRICT_PROTOTYPES = YES; 296 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 297 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; 298 | CLANG_WARN_UNREACHABLE_CODE = YES; 299 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 300 | COPY_PHASE_STRIP = NO; 301 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 302 | ENABLE_NS_ASSERTIONS = NO; 303 | ENABLE_STRICT_OBJC_MSGSEND = YES; 304 | GCC_C_LANGUAGE_STANDARD = gnu11; 305 | GCC_NO_COMMON_BLOCKS = YES; 306 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 307 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 308 | GCC_WARN_UNDECLARED_SELECTOR = YES; 309 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 310 | GCC_WARN_UNUSED_FUNCTION = YES; 311 | GCC_WARN_UNUSED_VARIABLE = YES; 312 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 313 | MTL_ENABLE_DEBUG_INFO = NO; 314 | MTL_FAST_MATH = YES; 315 | SDKROOT = iphoneos; 316 | SWIFT_COMPILATION_MODE = wholemodule; 317 | SWIFT_OPTIMIZATION_LEVEL = "-O"; 318 | VALIDATE_PRODUCT = YES; 319 | }; 320 | name = Release; 321 | }; 322 | 843F60B4299A84910079886F /* Debug */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 326 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 327 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 328 | CODE_SIGN_STYLE = Manual; 329 | CURRENT_PROJECT_VERSION = 1; 330 | DEVELOPMENT_ASSET_PATHS = "\"ChatGKD/Preview Content\""; 331 | DEVELOPMENT_TEAM = ""; 332 | "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 2M4WW2KKY5; 333 | ENABLE_PREVIEWS = YES; 334 | GENERATE_INFOPLIST_FILE = YES; 335 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 336 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 337 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 338 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 339 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 340 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 341 | LD_RUNPATH_SEARCH_PATHS = ( 342 | "$(inherited)", 343 | "@executable_path/Frameworks", 344 | ); 345 | MARKETING_VERSION = 1.0; 346 | PRODUCT_BUNDLE_IDENTIFIER = com.mydemos.ChatGKD; 347 | PRODUCT_NAME = "$(TARGET_NAME)"; 348 | PROVISIONING_PROFILE_SPECIFIER = ""; 349 | "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = SomeDemos; 350 | SWIFT_EMIT_LOC_STRINGS = YES; 351 | SWIFT_VERSION = 5.0; 352 | TARGETED_DEVICE_FAMILY = "1,2"; 353 | }; 354 | name = Debug; 355 | }; 356 | 843F60B5299A84910079886F /* Release */ = { 357 | isa = XCBuildConfiguration; 358 | buildSettings = { 359 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 360 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; 361 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 362 | CODE_SIGN_STYLE = Manual; 363 | CURRENT_PROJECT_VERSION = 1; 364 | DEVELOPMENT_ASSET_PATHS = "\"ChatGKD/Preview Content\""; 365 | DEVELOPMENT_TEAM = ""; 366 | "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 2M4WW2KKY5; 367 | ENABLE_PREVIEWS = YES; 368 | GENERATE_INFOPLIST_FILE = YES; 369 | INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; 370 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; 371 | INFOPLIST_KEY_UILaunchScreen_Generation = YES; 372 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 373 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; 374 | IPHONEOS_DEPLOYMENT_TARGET = 16.0; 375 | LD_RUNPATH_SEARCH_PATHS = ( 376 | "$(inherited)", 377 | "@executable_path/Frameworks", 378 | ); 379 | MARKETING_VERSION = 1.0; 380 | PRODUCT_BUNDLE_IDENTIFIER = com.mydemos.ChatGKD; 381 | PRODUCT_NAME = "$(TARGET_NAME)"; 382 | PROVISIONING_PROFILE_SPECIFIER = ""; 383 | "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = SomeDemos; 384 | SWIFT_EMIT_LOC_STRINGS = YES; 385 | SWIFT_VERSION = 5.0; 386 | TARGETED_DEVICE_FAMILY = "1,2"; 387 | }; 388 | name = Release; 389 | }; 390 | /* End XCBuildConfiguration section */ 391 | 392 | /* Begin XCConfigurationList section */ 393 | 843F609B299A84900079886F /* Build configuration list for PBXProject "ChatGKD" */ = { 394 | isa = XCConfigurationList; 395 | buildConfigurations = ( 396 | 843F60B1299A84910079886F /* Debug */, 397 | 843F60B2299A84910079886F /* Release */, 398 | ); 399 | defaultConfigurationIsVisible = 0; 400 | defaultConfigurationName = Release; 401 | }; 402 | 843F60B3299A84910079886F /* Build configuration list for PBXNativeTarget "ChatGKD" */ = { 403 | isa = XCConfigurationList; 404 | buildConfigurations = ( 405 | 843F60B4299A84910079886F /* Debug */, 406 | 843F60B5299A84910079886F /* Release */, 407 | ); 408 | defaultConfigurationIsVisible = 0; 409 | defaultConfigurationName = Release; 410 | }; 411 | /* End XCConfigurationList section */ 412 | 413 | /* Begin XCRemoteSwiftPackageReference section */ 414 | 843F60C4299A8F650079886F /* XCRemoteSwiftPackageReference "ChatGPTSwift" */ = { 415 | isa = XCRemoteSwiftPackageReference; 416 | repositoryURL = "https://github.com/alfianlosari/ChatGPTSwift.git"; 417 | requirement = { 418 | kind = upToNextMajorVersion; 419 | minimumVersion = 0.0.4; 420 | }; 421 | }; 422 | /* End XCRemoteSwiftPackageReference section */ 423 | 424 | /* Begin XCSwiftPackageProductDependency section */ 425 | 843F60C5299A8F650079886F /* ChatGPTSwift */ = { 426 | isa = XCSwiftPackageProductDependency; 427 | package = 843F60C4299A8F650079886F /* XCRemoteSwiftPackageReference "ChatGPTSwift" */; 428 | productName = ChatGPTSwift; 429 | }; 430 | /* End XCSwiftPackageProductDependency section */ 431 | 432 | /* Begin XCVersionGroup section */ 433 | 843F60AE299A84910079886F /* ChatGKD.xcdatamodeld */ = { 434 | isa = XCVersionGroup; 435 | children = ( 436 | 843F60AF299A84910079886F /* ChatGKD.xcdatamodel */, 437 | ); 438 | currentVersion = 843F60AF299A84910079886F /* ChatGKD.xcdatamodel */; 439 | path = ChatGKD.xcdatamodeld; 440 | sourceTree = ""; 441 | versionGroupType = wrapper.xcdatamodel; 442 | }; 443 | /* End XCVersionGroup section */ 444 | }; 445 | rootObject = 843F6098299A84900079886F /* Project object */; 446 | } 447 | -------------------------------------------------------------------------------- /ChatGKD.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ChatGKD.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ChatGKD.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved: -------------------------------------------------------------------------------- 1 | { 2 | "pins" : [ 3 | { 4 | "identity" : "chatgptswift", 5 | "kind" : "remoteSourceControl", 6 | "location" : "https://github.com/alfianlosari/ChatGPTSwift.git", 7 | "state" : { 8 | "revision" : "2fb57623d63ee88ceb3912c3b2b1806a6f6e1337", 9 | "version" : "0.0.4" 10 | } 11 | } 12 | ], 13 | "version" : 2 14 | } 15 | -------------------------------------------------------------------------------- /ChatGKD/Assets.xcassets/AccentColor.colorset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "colors" : [ 3 | { 4 | "idiom" : "universal" 5 | } 6 | ], 7 | "info" : { 8 | "author" : "xcode", 9 | "version" : 1 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /ChatGKD/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "filename" : "chatgkd-icon.png", 5 | "idiom" : "universal", 6 | "platform" : "ios", 7 | "size" : "1024x1024" 8 | } 9 | ], 10 | "info" : { 11 | "author" : "xcode", 12 | "version" : 1 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ChatGKD/Assets.xcassets/AppIcon.appiconset/chatgkd-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/ChatGKD/0ba1c7adb7fbfccd3887aa203b9335c9ec3ee36f/ChatGKD/Assets.xcassets/AppIcon.appiconset/chatgkd-icon.png -------------------------------------------------------------------------------- /ChatGKD/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ChatGKD/ChatGKD.xcdatamodeld/.xccurrentversion: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | _XCCurrentVersionName 6 | ChatGKD.xcdatamodel 7 | 8 | 9 | -------------------------------------------------------------------------------- /ChatGKD/ChatGKD.xcdatamodeld/ChatGKD.xcdatamodel/contents: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ChatGKD/ChatGKDApp.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatGKDApp.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | @main 11 | struct ChatGKDApp: App { 12 | let persistenceController = PersistenceController.shared 13 | 14 | var body: some Scene { 15 | WindowGroup { 16 | MainView() 17 | // ContentView() 18 | // .environment(\.managedObjectContext, persistenceController.container.viewContext) 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ChatGKD/ChatListView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatListView.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct ChatListView: View { 11 | @AppStorage("NameSwitch") var nameSwitch: Bool = false 12 | 13 | @State var currrentMessage = "" 14 | @State var isLoading = false { 15 | didSet { 16 | loadingUUID = nil 17 | } 18 | } 19 | @State var loadingUUID: UUID? 20 | @State var chats: [ChatModel] = [] 21 | 22 | @State var showingHistory = false 23 | 24 | @State var task: Task? 25 | 26 | let tapGesture = TapGesture() 27 | .onEnded { _ in 28 | UIApplication.shared.sendAction(#selector(UIResponder.resignFirstResponder), to: nil, from: nil, for: nil) 29 | } 30 | 31 | var body: some View { 32 | NavigationStack { 33 | VStack { 34 | ScrollView { 35 | ForEach(chats) { chat in 36 | Text("\(chat.isGPT ? "🤖️" : "🧑"):\(chat.isGPT && chat.message.isEmpty ? ChatGPTHelper.MessagePlaceholder : chat.message)") 37 | .bold(!chat.isGPT) 38 | .contextMenu { 39 | Button { 40 | UIPasteboard.general.string = chat.message 41 | } label: { 42 | Label("复制", systemImage: "doc.on.doc.fill") 43 | } 44 | } 45 | .foregroundColor( 46 | chat.message.starts(with: ChatGPTHelper.ChatErrorPrefix) ? .red : (loadingUUID == chat.id ? .secondary : .primary) 47 | ) 48 | .frame(maxWidth: .infinity, alignment: .leading) 49 | .padding(.horizontal) 50 | .padding(.vertical, 6) 51 | } 52 | } 53 | .scrollDismissesKeyboard(.interactively) 54 | .gesture(tapGesture) 55 | 56 | HStack(spacing: 4) { 57 | TextField(isLoading ? ChatGPTHelper.MessagePlaceholder : "请在此输入消息...", text: $currrentMessage) 58 | .padding(.leading, 12) 59 | .disabled(isLoading) 60 | 61 | Button { 62 | if isLoading { 63 | task?.cancel() 64 | 65 | if task == nil || task!.isCancelled { 66 | isLoading = false 67 | 68 | if chats.last!.isGPT { 69 | var last = chats.last! 70 | last.message.append(ChatGPTHelper.ChatStopTips) 71 | chats[chats.count-1] = last 72 | } else { 73 | chats.append(ChatModel(isGPT: true, message: ChatGPTHelper.ChatStopTips)) 74 | } 75 | 76 | ChatProvider.shared.saveOrUpdate(chats.last!) 77 | } 78 | } else { 79 | isLoading = true 80 | 81 | chats.append(ChatModel(isGPT: false, message: currrentMessage)) 82 | ChatProvider.shared.saveOrUpdate(chats.last!) 83 | 84 | currrentMessage = "" 85 | 86 | task = Task { 87 | do { 88 | // print(chats.last!.message) 89 | let stream = try await ChatGPTHelper.api.sendMessageStream(text: chats.last?.message ?? "") 90 | chats.append(ChatModel(isGPT: true, message: ChatGPTHelper.MessagePlaceholder)) 91 | loadingUUID = chats.last?.id 92 | 93 | var last = chats.last! 94 | 95 | for try await var line in stream { 96 | // 跳过空行 97 | if line.isEmpty || line == " " { 98 | continue 99 | } 100 | 101 | // 终止的任务 102 | if task == nil || task!.isCancelled { 103 | break 104 | } 105 | 106 | // 去除占位 107 | if last.message == ChatGPTHelper.MessagePlaceholder { 108 | last.message = "" 109 | 110 | // 处理空格,仅第一行 111 | if line.starts(with: " ") { 112 | line.removeFirst() 113 | } 114 | } 115 | 116 | last.message.append(line) 117 | chats[chats.count-1] = last 118 | 119 | // print(line) 120 | } 121 | isLoading = false 122 | 123 | ChatProvider.shared.saveOrUpdate(chats.last!) 124 | } catch { 125 | if !chats.last!.isGPT { 126 | chats.append(ChatModel(isGPT: true, message: "\(ChatGPTHelper.ChatErrorPrefix) [\(error.localizedDescription)]")) 127 | isLoading = false 128 | } 129 | } 130 | } 131 | } 132 | } label: { 133 | Group { 134 | if isLoading { 135 | Image(systemName: "stop.fill") 136 | .font(.system(size: 12, weight: .bold)) 137 | .frame(width: 26, height: 26) 138 | .foregroundColor(.white) 139 | .background(Color.red) 140 | .cornerRadius(13) 141 | } else { 142 | Image(systemName: "arrow.up") 143 | .font(.system(size: 16, weight: .bold)) 144 | .frame(width: 26, height: 26) 145 | .foregroundColor(.white) 146 | .background(Color.blue) 147 | .cornerRadius(13) 148 | } 149 | } 150 | } 151 | .buttonStyle(BorderlessButtonStyle()) 152 | .padding(4) 153 | } 154 | .overlay( 155 | RoundedRectangle(cornerRadius: 17) 156 | .stroke(Color(uiColor: .systemGray4)) 157 | ) 158 | .padding(.horizontal) 159 | .padding(.vertical, 6) 160 | .toolbar { 161 | ToolbarItem(placement: .navigationBarLeading) { 162 | Button { 163 | showingHistory = true 164 | } label: { 165 | Image(systemName: "clock") 166 | } 167 | } 168 | 169 | ToolbarItem(placement: .navigationBarTrailing) { 170 | Button { 171 | ChatGPTHelper.renew() 172 | 173 | chats = [] 174 | task?.cancel() 175 | } label: { 176 | Image(systemName: "arrow.clockwise") 177 | } 178 | } 179 | } 180 | .sheet(isPresented: $showingHistory) { 181 | HistoryChatView() 182 | } 183 | } 184 | .navigationTitle(nameSwitch ? "ChatGKD" : "ChatGPT") 185 | } 186 | } 187 | } 188 | 189 | struct ChatListView_Previews: PreviewProvider { 190 | static var previews: some View { 191 | ChatListView() 192 | } 193 | } 194 | -------------------------------------------------------------------------------- /ChatGKD/ContentView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ContentView.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import SwiftUI 9 | import CoreData 10 | 11 | struct ContentView: View { 12 | @Environment(\.managedObjectContext) private var viewContext 13 | 14 | @FetchRequest( 15 | sortDescriptors: [NSSortDescriptor(keyPath: \Item.timestamp, ascending: true)], 16 | animation: .default) 17 | private var items: FetchedResults 18 | 19 | var body: some View { 20 | NavigationView { 21 | List { 22 | ForEach(items) { item in 23 | NavigationLink { 24 | Text("Item at \(item.timestamp!, formatter: itemFormatter)") 25 | } label: { 26 | Text(item.timestamp!, formatter: itemFormatter) 27 | } 28 | } 29 | .onDelete(perform: deleteItems) 30 | } 31 | .toolbar { 32 | ToolbarItem(placement: .navigationBarTrailing) { 33 | EditButton() 34 | } 35 | ToolbarItem { 36 | Button(action: addItem) { 37 | Label("Add Item", systemImage: "plus") 38 | } 39 | } 40 | } 41 | Text("Select an item") 42 | } 43 | } 44 | 45 | private func addItem() { 46 | withAnimation { 47 | let newItem = Item(context: viewContext) 48 | newItem.timestamp = Date() 49 | 50 | do { 51 | try viewContext.save() 52 | } catch { 53 | // Replace this implementation with code to handle the error appropriately. 54 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 55 | let nsError = error as NSError 56 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") 57 | } 58 | } 59 | } 60 | 61 | private func deleteItems(offsets: IndexSet) { 62 | withAnimation { 63 | offsets.map { items[$0] }.forEach(viewContext.delete) 64 | 65 | do { 66 | try viewContext.save() 67 | } catch { 68 | // Replace this implementation with code to handle the error appropriately. 69 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 70 | let nsError = error as NSError 71 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") 72 | } 73 | } 74 | } 75 | } 76 | 77 | private let itemFormatter: DateFormatter = { 78 | let formatter = DateFormatter() 79 | formatter.dateStyle = .short 80 | formatter.timeStyle = .medium 81 | return formatter 82 | }() 83 | 84 | struct ContentView_Previews: PreviewProvider { 85 | static var previews: some View { 86 | ContentView().environment(\.managedObjectContext, PersistenceController.preview.container.viewContext) 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /ChatGKD/HistoryChatView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // HistoryChatView.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/14. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct HistoryChatView: View { 11 | @State var chats: [ChatModel] = [] 12 | 13 | var body: some View { 14 | NavigationStack { 15 | List { 16 | if chats.isEmpty { 17 | Text("暂无历史对话") 18 | } else { 19 | ForEach(chats) { chat in 20 | Text("\(chat.isGPT ? "🤖️" : "🧑"):\(chat.message)") 21 | .bold(!chat.isGPT) 22 | .contextMenu { 23 | Button { 24 | UIPasteboard.general.string = chat.message 25 | } label: { 26 | Label("复制", systemImage: "doc.on.doc.fill") 27 | } 28 | } 29 | } 30 | .onDelete { indexSet in 31 | ChatProvider.shared.remove(indexSet) 32 | } 33 | } 34 | } 35 | .navigationTitle("历史对话") 36 | .onAppear { 37 | chats = ChatProvider.shared.search() 38 | } 39 | .toolbar { 40 | ToolbarItem { 41 | Button { 42 | ChatProvider.shared.clear() 43 | chats = ChatProvider.shared.search() 44 | } label: { 45 | Image(systemName: "trash.fill") 46 | .foregroundColor(Color.red) 47 | } 48 | 49 | } 50 | } 51 | } 52 | } 53 | } 54 | 55 | struct HistoryChatView_Previews: PreviewProvider { 56 | static var previews: some View { 57 | HistoryChatView() 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /ChatGKD/MainView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MainView.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct MainView: View { 11 | var body: some View { 12 | TabView { 13 | ChatListView() 14 | .tabItem { 15 | Image(systemName: "ellipsis.bubble.fill") 16 | .font(.system(size: 22)) 17 | } 18 | SettingsView() 19 | .tabItem { 20 | Image(systemName: "gearshape.fill") 21 | .font(.system(size: 22)) 22 | } 23 | } 24 | } 25 | } 26 | 27 | struct MainView_Previews: PreviewProvider { 28 | static var previews: some View { 29 | MainView() 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ChatGKD/Model/ChatModel.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatModel.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import Foundation 9 | 10 | struct ChatModel: Identifiable { 11 | var id = UUID() 12 | 13 | var isGPT: Bool 14 | var message: String 15 | } 16 | 17 | extension ChatEntity { 18 | var toModel: ChatModel { 19 | ChatModel(id: id ?? UUID(), isGPT: isAI, message: message ?? "") 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /ChatGKD/Persistence.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Persistence.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import CoreData 9 | 10 | struct PersistenceController { 11 | static let shared = PersistenceController() 12 | 13 | static var preview: PersistenceController = { 14 | let result = PersistenceController(inMemory: true) 15 | let viewContext = result.container.viewContext 16 | for _ in 0..<10 { 17 | let newItem = Item(context: viewContext) 18 | newItem.timestamp = Date() 19 | } 20 | do { 21 | try viewContext.save() 22 | } catch { 23 | // Replace this implementation with code to handle the error appropriately. 24 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 25 | let nsError = error as NSError 26 | fatalError("Unresolved error \(nsError), \(nsError.userInfo)") 27 | } 28 | return result 29 | }() 30 | 31 | let container: NSPersistentContainer 32 | 33 | init(inMemory: Bool = false) { 34 | container = NSPersistentContainer(name: "ChatGKD") 35 | if inMemory { 36 | container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null") 37 | } 38 | container.loadPersistentStores(completionHandler: { (storeDescription, error) in 39 | if let error = error as NSError? { 40 | // Replace this implementation with code to handle the error appropriately. 41 | // fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 42 | 43 | /* 44 | Typical reasons for an error here include: 45 | * The parent directory does not exist, cannot be created, or disallows writing. 46 | * The persistent store is not accessible, due to permissions or data protection when the device is locked. 47 | * The device is out of space. 48 | * The store could not be migrated to the current model version. 49 | Check the error message to determine what the actual problem was. 50 | */ 51 | fatalError("Unresolved error \(error), \(error.userInfo)") 52 | } 53 | }) 54 | container.viewContext.automaticallyMergesChangesFromParent = true 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /ChatGKD/Preview Content/Preview Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "author" : "xcode", 4 | "version" : 1 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ChatGKD/SettingsView.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SettingsView.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import SwiftUI 9 | 10 | struct SettingsView: View { 11 | @AppStorage("NameSwitch") var nameSwitch: Bool = false 12 | 13 | var body: some View { 14 | NavigationView { 15 | List { 16 | Toggle("名称切换", isOn: $nameSwitch) 17 | 18 | Text("Powered by kingcos with Love.") 19 | } 20 | .navigationTitle("设置") 21 | } 22 | } 23 | } 24 | 25 | struct SettingsView_Previews: PreviewProvider { 26 | static var previews: some View { 27 | SettingsView() 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /ChatGKD/Utils/ChatGPTHelper.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatGPTHelper.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import Foundation 9 | import ChatGPTSwift 10 | 11 | struct ChatGPTHelper { 12 | private static var _api: ChatGPTAPI? 13 | 14 | static var api: ChatGPTAPI { 15 | if _api == nil { 16 | renew() 17 | } 18 | 19 | return _api! 20 | } 21 | 22 | static func renew() { 23 | _api = ChatGPTAPI(apiKey: "YOUR_API_KEY") 24 | } 25 | 26 | static let MessagePlaceholder = "💭 思考中..." 27 | static let ChatErrorPrefix = "[出错咯]" 28 | static let ChatStopTips = "[已终止]" 29 | } 30 | -------------------------------------------------------------------------------- /ChatGKD/Utils/ChatProvider.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ChatProvider.swift 3 | // ChatGKD 4 | // 5 | // Created by kingcos on 2023/2/13. 6 | // 7 | 8 | import Foundation 9 | import CoreData 10 | 11 | struct ChatProvider { 12 | static let shared = ChatProvider() 13 | 14 | let persistenceController = PersistenceController.shared 15 | var viewContext: NSManagedObjectContext { 16 | persistenceController.container.viewContext 17 | } 18 | 19 | func _search() -> [ChatEntity] { 20 | var items = [ChatEntity]() 21 | let request = ChatEntity.fetchRequest() 22 | 23 | do { 24 | items = try viewContext.fetch(request) 25 | } catch { 26 | debugPrint("error retrieving cards: \(error)") 27 | } 28 | 29 | return items 30 | } 31 | 32 | func search() -> [ChatModel] { 33 | return _search().map { $0.toModel } 34 | } 35 | 36 | 37 | func saveOrUpdate(_ item: ChatModel) { 38 | let request = ChatEntity.fetchRequest() 39 | request.predicate = NSPredicate(format: "id == %@", item.id.uuidString) 40 | 41 | if let old = try? viewContext.fetch(request).first { 42 | // 1. 更新 43 | old.id = item.id 44 | old.isAI = item.isGPT 45 | old.message = item.message 46 | } else { 47 | // 2. 新增 48 | let new = ChatEntity(context: viewContext) 49 | new.id = item.id 50 | new.isAI = item.isGPT 51 | new.message = item.message 52 | } 53 | 54 | if viewContext.hasChanges { 55 | do { 56 | try viewContext.save() 57 | } catch { 58 | let nserror = error as NSError 59 | debugPrint("Unresolved error \(nserror), \(nserror.userInfo)") 60 | } 61 | } 62 | } 63 | 64 | func clear() { 65 | let deleteRequest = NSBatchDeleteRequest(fetchRequest: ChatEntity.fetchRequest()) 66 | 67 | do { 68 | try viewContext.execute(deleteRequest) 69 | try viewContext.save() 70 | } catch { 71 | debugPrint("error retrieving cards: \(error)") 72 | } 73 | } 74 | 75 | func remove(_ indexSet: IndexSet) { 76 | let items = _search() 77 | for index in indexSet { 78 | let entity = items[index] 79 | 80 | viewContext.delete(entity) 81 | if viewContext.hasChanges { 82 | do { 83 | try viewContext.save() 84 | } catch { 85 | let nserror = error as NSError 86 | debugPrint("Unresolved error \(nserror), \(nserror.userInfo)") 87 | } 88 | } 89 | } 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ChatGKD 2 | 3 | A new app for ChatGPT in SwiftUI & [Vue 3](https://kingcos.me/ChatGKD). 4 | 5 | 现已支持最新 Chat API!赶快体验类似 ChatGPT 一般的能力吧~ 6 | 7 | > What is *ChatGKD*? 8 | > 9 | > GKD stands for Gao(搞)Kuai(快)Dian(点), which means faster in Chinese. 10 | 11 | ## Preview 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 |
Web
App
24 | 25 | ## Features 26 | 27 | - [x] Custom prompt (web version) 28 | - [x] Support new gpt-3.5-turbo model (web version) 29 | - [x] Support PWA (web version) 30 | 31 | ## Usages 32 | 33 | ### For Web 34 | 35 | Open [kingcos.me/ChatGKD](https://kingcos.me/ChatGKD), then just input your APY key as followed: 36 | 37 | ``` 38 | key:YOUR_API_KEY 39 | ``` 40 | 41 | And, enjoy. 42 | 43 | ### For App 44 | 45 | Replace your API key in `Utils/ChatGPTHelper.swift`: 46 | 47 | ```swift 48 | _api = ChatGPTAPI(apiKey: "YOUR_API_KEY") 49 | ``` 50 | 51 | Build, and enjoy. 52 | -------------------------------------------------------------------------------- /assets/index-c837ffa6.css: -------------------------------------------------------------------------------- 1 | body[data-v-10287b46]{padding:0;margin:0}.chatgkd[data-v-10287b46]{display:flex;flex-direction:column;height:100%;padding:50px 10px}.header[data-v-10287b46]{position:fixed;left:0;right:0;top:0;height:50px;display:flex;align-items:center;padding:10px;background-color:#e2e2e2}.title[data-v-10287b46]{font-size:24px;font-weight:600}.subtitle[data-v-10287b46]{font-size:12px}.title-container[data-v-10287b46]{flex:1;display:flex;align-items:center;flex-direction:column}.button[data-v-10287b46]{color:#00f;border:1px solid #000;padding:5px;border-radius:5px}.footer[data-v-10287b46]{position:fixed;left:0;right:0;height:50px;width:100%;display:flex;flex-direction:row;justify-content:space-between;align-items:center}.help[data-v-10287b46]{position:fixed;left:0;right:0;top:70px;background-color:#5361f6f2;color:#fff;padding:10px;margin:10px;border-radius:10px}.list[data-v-10287b46]{flex:1;overflow-y:auto;margin-top:30px;margin-bottom:10px;padding:10px 10px 0;border-radius:10px;background-color:#efefef}.tips[data-v-10287b46],.item[data-v-10287b46]{padding-bottom:10px}.human-text[data-v-10287b46]{font-weight:600}.input-wrapper[data-v-10287b46]{flex:1;margin-right:10px;height:100%}.input-wrapper input[data-v-10287b46]{width:100%;height:100%;padding-left:10px;font-size:14px;border:none;outline:none;background-color:#e2e2e2}.footer-button[data-v-10287b46]{width:80px;height:100%;font-size:16px;padding-left:10px;padding-right:10px}body{padding:0;margin:0} 2 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 19 | 20 | ChatGKD 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /manifest.webmanifest: -------------------------------------------------------------------------------- 1 | {"name":"chatgkd-web","short_name":"chatgkd-web","start_url":"/ChatGKD/","display":"standalone","background_color":"#ffffff","lang":"en","scope":"/ChatGKD/"} 2 | -------------------------------------------------------------------------------- /registerSW.js: -------------------------------------------------------------------------------- 1 | if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('/ChatGKD/sw.js', { scope: '/ChatGKD/' })})} -------------------------------------------------------------------------------- /resources/chatgkd-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/ChatGKD/0ba1c7adb7fbfccd3887aa203b9335c9ec3ee36f/resources/chatgkd-icon.png -------------------------------------------------------------------------------- /resources/history.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/ChatGKD/0ba1c7adb7fbfccd3887aa203b9335c9ec3ee36f/resources/history.PNG -------------------------------------------------------------------------------- /resources/main.PNG: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/ChatGKD/0ba1c7adb7fbfccd3887aa203b9335c9ec3ee36f/resources/main.PNG -------------------------------------------------------------------------------- /resources/web.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kingcos/ChatGKD/0ba1c7adb7fbfccd3887aa203b9335c9ec3ee36f/resources/web.jpeg -------------------------------------------------------------------------------- /sw.js: -------------------------------------------------------------------------------- 1 | if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise((s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()})).then((()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e})));self.define=(n,r)=>{const t=e||("document"in self?document.currentScript.src:"")||location.href;if(s[t])return;let c={};const o=e=>i(e,t),l={module:{uri:t},exports:c,require:o};s[t]=Promise.all(n.map((e=>l[e]||o(e)))).then((e=>(r(...e),c)))}}define(["./workbox-7369c0e1"],(function(e){"use strict";self.addEventListener("message",(e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()})),e.precacheAndRoute([{url:"assets/index-47f8a1c6.js",revision:null},{url:"assets/index-c837ffa6.css",revision:null},{url:"index.html",revision:"205e3672ce3cdd756ebaac4ea9290858"},{url:"registerSW.js",revision:"c3ece67fa5e25fbe9cf93993ce6d0614"},{url:"manifest.webmanifest",revision:"b558c04496395c038fb7c77aeab9ebf4"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html")))})); 2 | -------------------------------------------------------------------------------- /web/.eslintrc.cjs: -------------------------------------------------------------------------------- 1 | /* eslint-env node */ 2 | require("@rushstack/eslint-patch/modern-module-resolution"); 3 | 4 | module.exports = { 5 | root: true, 6 | extends: [ 7 | "plugin:vue/vue3-essential", 8 | "eslint:recommended", 9 | "@vue/eslint-config-typescript", 10 | "@vue/eslint-config-prettier", 11 | ], 12 | parserOptions: { 13 | ecmaVersion: "latest", 14 | }, 15 | }; 16 | -------------------------------------------------------------------------------- /web/.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | pnpm-debug.log* 8 | lerna-debug.log* 9 | 10 | node_modules 11 | .DS_Store 12 | dist 13 | dist-ssr 14 | coverage 15 | *.local 16 | 17 | /cypress/videos/ 18 | /cypress/screenshots/ 19 | 20 | # Editor directories and files 21 | .vscode/* 22 | !.vscode/extensions.json 23 | .idea 24 | *.suo 25 | *.ntvs* 26 | *.njsproj 27 | *.sln 28 | *.sw? 29 | -------------------------------------------------------------------------------- /web/.prettierrc.json: -------------------------------------------------------------------------------- 1 | {} -------------------------------------------------------------------------------- /web/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": ["Vue.volar", "Vue.vscode-typescript-vue-plugin"] 3 | } 4 | -------------------------------------------------------------------------------- /web/README.md: -------------------------------------------------------------------------------- 1 | # chatgkd-web 2 | 3 | This template should help get you started developing with Vue 3 in Vite. 4 | 5 | ## Recommended IDE Setup 6 | 7 | [VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin). 8 | 9 | ## Type Support for `.vue` Imports in TS 10 | 11 | TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types. 12 | 13 | If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps: 14 | 15 | 1. Disable the built-in TypeScript Extension 16 | 1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette 17 | 2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)` 18 | 2. Reload the VSCode window by running `Developer: Reload Window` from the command palette. 19 | 20 | ## Customize configuration 21 | 22 | See [Vite Configuration Reference](https://vitejs.dev/config/). 23 | 24 | ## Project Setup 25 | 26 | ```sh 27 | npm install 28 | ``` 29 | 30 | ### Compile and Hot-Reload for Development 31 | 32 | ```sh 33 | npm run dev 34 | ``` 35 | 36 | ### Type-Check, Compile and Minify for Production 37 | 38 | ```sh 39 | npm run build 40 | ``` 41 | 42 | ### Lint with [ESLint](https://eslint.org/) 43 | 44 | ```sh 45 | npm run lint 46 | ``` 47 | -------------------------------------------------------------------------------- /web/assets/index-452cecbb.js: -------------------------------------------------------------------------------- 1 | var Fr=Object.defineProperty;var Mr=(e,t,n)=>t in e?Fr(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var gt=(e,t,n)=>(Mr(e,typeof t!="symbol"?t+"":t,n),n);(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const r of document.querySelectorAll('link[rel="modulepreload"]'))s(r);new MutationObserver(r=>{for(const i of r)if(i.type==="childList")for(const o of i.addedNodes)o.tagName==="LINK"&&o.rel==="modulepreload"&&s(o)}).observe(document,{childList:!0,subtree:!0});function n(r){const i={};return r.integrity&&(i.integrity=r.integrity),r.referrerpolicy&&(i.referrerPolicy=r.referrerpolicy),r.crossorigin==="use-credentials"?i.credentials="include":r.crossorigin==="anonymous"?i.credentials="omit":i.credentials="same-origin",i}function s(r){if(r.ep)return;r.ep=!0;const i=n(r);fetch(r.href,i)}})();function Fn(e,t){const n=Object.create(null),s=e.split(",");for(let r=0;r!!n[r.toLowerCase()]:r=>!!n[r]}function zt(e){if(M(e)){const t={};for(let n=0;n{if(n){const s=n.split(Rr);s.length>1&&(t[s[0].trim()]=s[1].trim())}}),t}function Mn(e){let t="";if(G(e))t=e;else if(M(e))for(let n=0;nG(e)?e:e==null?"":M(e)||W(e)&&(e.toString===Ns||!K(e.toString))?JSON.stringify(e,Rs,2):String(e),Rs=(e,t)=>t&&t.__v_isRef?Rs(e,t.value):it(t)?{[`Map(${t.size})`]:[...t.entries()].reduce((n,[s,r])=>(n[`${s} =>`]=r,n),{})}:Ls(t)?{[`Set(${t.size})`]:[...t.values()]}:W(t)&&!M(t)&&!Hs(t)?String(t):t,D={},rt=[],ye=()=>{},jr=()=>!1,Br=/^on[^a-z]/,qt=e=>Br.test(e),Kn=e=>e.startsWith("onUpdate:"),ne=Object.assign,Rn=(e,t)=>{const n=e.indexOf(t);n>-1&&e.splice(n,1)},Ur=Object.prototype.hasOwnProperty,S=(e,t)=>Ur.call(e,t),M=Array.isArray,it=e=>Yt(e)==="[object Map]",Ls=e=>Yt(e)==="[object Set]",K=e=>typeof e=="function",G=e=>typeof e=="string",Ln=e=>typeof e=="symbol",W=e=>e!==null&&typeof e=="object",Ss=e=>W(e)&&K(e.then)&&K(e.catch),Ns=Object.prototype.toString,Yt=e=>Ns.call(e),$r=e=>Yt(e).slice(8,-1),Hs=e=>Yt(e)==="[object Object]",Sn=e=>G(e)&&e!=="NaN"&&e[0]!=="-"&&""+parseInt(e,10)===e,St=Fn(",key,ref,ref_for,ref_key,onVnodeBeforeMount,onVnodeMounted,onVnodeBeforeUpdate,onVnodeUpdated,onVnodeBeforeUnmount,onVnodeUnmounted"),Jt=e=>{const t=Object.create(null);return n=>t[n]||(t[n]=e(n))},Dr=/-(\w)/g,ct=Jt(e=>e.replace(Dr,(t,n)=>n?n.toUpperCase():"")),kr=/\B([A-Z])/g,Qe=Jt(e=>e.replace(kr,"-$1").toLowerCase()),js=Jt(e=>e.charAt(0).toUpperCase()+e.slice(1)),fn=Jt(e=>e?`on${js(e)}`:""),xt=(e,t)=>!Object.is(e,t),Nt=(e,t)=>{for(let n=0;n{Object.defineProperty(e,t,{configurable:!0,enumerable:!1,value:n})},mn=e=>{const t=parseFloat(e);return isNaN(t)?e:t};let ns;const Wr=()=>ns||(ns=typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:typeof global<"u"?global:{});let ge;class zr{constructor(t=!1){this.detached=t,this._active=!0,this.effects=[],this.cleanups=[],this.parent=ge,!t&&ge&&(this.index=(ge.scopes||(ge.scopes=[])).push(this)-1)}get active(){return this._active}run(t){if(this._active){const n=ge;try{return ge=this,t()}finally{ge=n}}}on(){ge=this}off(){ge=this.parent}stop(t){if(this._active){let n,s;for(n=0,s=this.effects.length;n{const t=new Set(e);return t.w=0,t.n=0,t},Bs=e=>(e.w&Be)>0,Us=e=>(e.n&Be)>0,Jr=({deps:e})=>{if(e.length)for(let t=0;t{const{deps:t}=e;if(t.length){let n=0;for(let s=0;s{(p==="length"||p>=u)&&l.push(a)})}else switch(n!==void 0&&l.push(o.get(n)),t){case"add":M(e)?Sn(n)&&l.push(o.get("length")):(l.push(o.get(Xe)),it(e)&&l.push(o.get(yn)));break;case"delete":M(e)||(l.push(o.get(Xe)),it(e)&&l.push(o.get(yn)));break;case"set":it(e)&&l.push(o.get(Xe));break}if(l.length===1)l[0]&&xn(l[0]);else{const u=[];for(const a of l)a&&u.push(...a);xn(Nn(u))}}function xn(e,t){const n=M(e)?e:[...e];for(const s of n)s.computed&&rs(s);for(const s of n)s.computed||rs(s)}function rs(e,t){(e!==_e||e.allowRecurse)&&(e.scheduler?e.scheduler():e.run())}const Gr=Fn("__proto__,__v_isRef,__isVue"),ks=new Set(Object.getOwnPropertyNames(Symbol).filter(e=>e!=="arguments"&&e!=="caller").map(e=>Symbol[e]).filter(Ln)),Xr=jn(),Zr=jn(!1,!0),Qr=jn(!0),is=ei();function ei(){const e={};return["includes","indexOf","lastIndexOf"].forEach(t=>{e[t]=function(...n){const s=N(this);for(let i=0,o=this.length;i{e[t]=function(...n){at();const s=N(this)[t].apply(this,n);return dt(),s}}),e}function ti(e){const t=N(this);return oe(t,"has",e),t.hasOwnProperty(e)}function jn(e=!1,t=!1){return function(s,r,i){if(r==="__v_isReactive")return!e;if(r==="__v_isReadonly")return e;if(r==="__v_isShallow")return t;if(r==="__v_raw"&&i===(e?t?_i:Js:t?Ys:qs).get(s))return s;const o=M(s);if(!e){if(o&&S(is,r))return Reflect.get(is,r,i);if(r==="hasOwnProperty")return ti}const l=Reflect.get(s,r,i);return(Ln(r)?ks.has(r):Gr(r))||(e||oe(s,"get",r),t)?l:te(l)?o&&Sn(r)?l:l.value:W(l)?e?Vs(l):Gt(l):l}}const ni=Ws(),si=Ws(!0);function Ws(e=!1){return function(n,s,r,i){let o=n[s];if(ft(o)&&te(o)&&!te(r))return!1;if(!e&&(!Dt(r)&&!ft(r)&&(o=N(o),r=N(r)),!M(n)&&te(o)&&!te(r)))return o.value=r,!0;const l=M(n)&&Sn(s)?Number(s)e,Vt=e=>Reflect.getPrototypeOf(e);function Ot(e,t,n=!1,s=!1){e=e.__v_raw;const r=N(e),i=N(t);n||(t!==i&&oe(r,"get",t),oe(r,"get",i));const{has:o}=Vt(r),l=s?Bn:n?Dn:Ct;if(o.call(r,t))return l(e.get(t));if(o.call(r,i))return l(e.get(i));e!==r&&e.get(t)}function It(e,t=!1){const n=this.__v_raw,s=N(n),r=N(e);return t||(e!==r&&oe(s,"has",e),oe(s,"has",r)),e===r?n.has(e):n.has(e)||n.has(r)}function Ft(e,t=!1){return e=e.__v_raw,!t&&oe(N(e),"iterate",Xe),Reflect.get(e,"size",e)}function os(e){e=N(e);const t=N(this);return Vt(t).has.call(t,e)||(t.add(e),Ke(t,"add",e,e)),this}function ls(e,t){t=N(t);const n=N(this),{has:s,get:r}=Vt(n);let i=s.call(n,e);i||(e=N(e),i=s.call(n,e));const o=r.call(n,e);return n.set(e,t),i?xt(t,o)&&Ke(n,"set",e,t):Ke(n,"add",e,t),this}function cs(e){const t=N(this),{has:n,get:s}=Vt(t);let r=n.call(t,e);r||(e=N(e),r=n.call(t,e)),s&&s.call(t,e);const i=t.delete(e);return r&&Ke(t,"delete",e,void 0),i}function fs(){const e=N(this),t=e.size!==0,n=e.clear();return t&&Ke(e,"clear",void 0,void 0),n}function Mt(e,t){return function(s,r){const i=this,o=i.__v_raw,l=N(o),u=t?Bn:e?Dn:Ct;return!e&&oe(l,"iterate",Xe),o.forEach((a,p)=>s.call(r,u(a),u(p),i))}}function Kt(e,t,n){return function(...s){const r=this.__v_raw,i=N(r),o=it(i),l=e==="entries"||e===Symbol.iterator&&o,u=e==="keys"&&o,a=r[e](...s),p=n?Bn:t?Dn:Ct;return!t&&oe(i,"iterate",u?yn:Xe),{next(){const{value:x,done:C}=a.next();return C?{value:x,done:C}:{value:l?[p(x[0]),p(x[1])]:p(x),done:C}},[Symbol.iterator](){return this}}}}function Se(e){return function(...t){return e==="delete"?!1:this}}function fi(){const e={get(i){return Ot(this,i)},get size(){return Ft(this)},has:It,add:os,set:ls,delete:cs,clear:fs,forEach:Mt(!1,!1)},t={get(i){return Ot(this,i,!1,!0)},get size(){return Ft(this)},has:It,add:os,set:ls,delete:cs,clear:fs,forEach:Mt(!1,!0)},n={get(i){return Ot(this,i,!0)},get size(){return Ft(this,!0)},has(i){return It.call(this,i,!0)},add:Se("add"),set:Se("set"),delete:Se("delete"),clear:Se("clear"),forEach:Mt(!0,!1)},s={get(i){return Ot(this,i,!0,!0)},get size(){return Ft(this,!0)},has(i){return It.call(this,i,!0)},add:Se("add"),set:Se("set"),delete:Se("delete"),clear:Se("clear"),forEach:Mt(!0,!0)};return["keys","values","entries",Symbol.iterator].forEach(i=>{e[i]=Kt(i,!1,!1),n[i]=Kt(i,!0,!1),t[i]=Kt(i,!1,!0),s[i]=Kt(i,!0,!0)}),[e,n,t,s]}const[ui,ai,di,hi]=fi();function Un(e,t){const n=t?e?hi:di:e?ai:ui;return(s,r,i)=>r==="__v_isReactive"?!e:r==="__v_isReadonly"?e:r==="__v_raw"?s:Reflect.get(S(n,r)&&r in s?n:s,r,i)}const pi={get:Un(!1,!1)},gi={get:Un(!1,!0)},mi={get:Un(!0,!1)},qs=new WeakMap,Ys=new WeakMap,Js=new WeakMap,_i=new WeakMap;function bi(e){switch(e){case"Object":case"Array":return 1;case"Map":case"Set":case"WeakMap":case"WeakSet":return 2;default:return 0}}function yi(e){return e.__v_skip||!Object.isExtensible(e)?0:bi($r(e))}function Gt(e){return ft(e)?e:$n(e,!1,zs,pi,qs)}function xi(e){return $n(e,!1,ci,gi,Ys)}function Vs(e){return $n(e,!0,li,mi,Js)}function $n(e,t,n,s,r){if(!W(e)||e.__v_raw&&!(t&&e.__v_isReactive))return e;const i=r.get(e);if(i)return i;const o=yi(e);if(o===0)return e;const l=new Proxy(e,o===2?s:n);return r.set(e,l),l}function ot(e){return ft(e)?ot(e.__v_raw):!!(e&&e.__v_isReactive)}function ft(e){return!!(e&&e.__v_isReadonly)}function Dt(e){return!!(e&&e.__v_isShallow)}function Gs(e){return ot(e)||ft(e)}function N(e){const t=e&&e.__v_raw;return t?N(t):e}function Xs(e){return $t(e,"__v_skip",!0),e}const Ct=e=>W(e)?Gt(e):e,Dn=e=>W(e)?Vs(e):e;function Zs(e){He&&_e&&(e=N(e),Ds(e.dep||(e.dep=Nn())))}function Qs(e,t){e=N(e);const n=e.dep;n&&xn(n)}function te(e){return!!(e&&e.__v_isRef===!0)}function ke(e){return Ci(e,!1)}function Ci(e,t){return te(e)?e:new wi(e,t)}class wi{constructor(t,n){this.__v_isShallow=n,this.dep=void 0,this.__v_isRef=!0,this._rawValue=n?t:N(t),this._value=n?t:Ct(t)}get value(){return Zs(this),this._value}set value(t){const n=this.__v_isShallow||Dt(t)||ft(t);t=n?t:N(t),xt(t,this._rawValue)&&(this._rawValue=t,this._value=n?t:Ct(t),Qs(this))}}function er(e){return te(e)?e.value:e}const vi={get:(e,t,n)=>er(Reflect.get(e,t,n)),set:(e,t,n,s)=>{const r=e[t];return te(r)&&!te(n)?(r.value=n,!0):Reflect.set(e,t,n,s)}};function tr(e){return ot(e)?e:new Proxy(e,vi)}var nr;class Ti{constructor(t,n,s,r){this._setter=n,this.dep=void 0,this.__v_isRef=!0,this[nr]=!1,this._dirty=!0,this.effect=new Hn(t,()=>{this._dirty||(this._dirty=!0,Qs(this))}),this.effect.computed=this,this.effect.active=this._cacheable=!r,this.__v_isReadonly=s}get value(){const t=N(this);return Zs(t),(t._dirty||!t._cacheable)&&(t._dirty=!1,t._value=t.effect.run()),t._value}set value(t){this._setter(t)}}nr="__v_isReadonly";function Ei(e,t,n=!1){let s,r;const i=K(e);return i?(s=e,r=ye):(s=e.get,r=e.set),new Ti(s,r,i||!r,n)}function je(e,t,n,s){let r;try{r=s?e(...s):e()}catch(i){Xt(i,t,n)}return r}function de(e,t,n,s){if(K(e)){const i=je(e,t,n,s);return i&&Ss(i)&&i.catch(o=>{Xt(o,t,n)}),i}const r=[];for(let i=0;i>>1;vt(ee[s])Ae&&ee.splice(t,1)}function Fi(e){M(e)?lt.push(...e):(!Fe||!Fe.includes(e,e.allowRecurse?Ye+1:Ye))&<.push(e),rr()}function us(e,t=wt?Ae+1:0){for(;tvt(n)-vt(s)),Ye=0;Yee.id==null?1/0:e.id,Mi=(e,t)=>{const n=vt(e)-vt(t);if(n===0){if(e.pre&&!t.pre)return-1;if(t.pre&&!e.pre)return 1}return n};function or(e){Cn=!1,wt=!0,ee.sort(Mi);const t=ye;try{for(Ae=0;AeG(O)?O.trim():O)),x&&(r=n.map(mn))}let l,u=s[l=fn(t)]||s[l=fn(ct(t))];!u&&i&&(u=s[l=fn(Qe(t))]),u&&de(u,e,6,r);const a=s[l+"Once"];if(a){if(!e.emitted)e.emitted={};else if(e.emitted[l])return;e.emitted[l]=!0,de(a,e,6,r)}}function lr(e,t,n=!1){const s=t.emitsCache,r=s.get(e);if(r!==void 0)return r;const i=e.emits;let o={},l=!1;if(!K(e)){const u=a=>{const p=lr(a,t,!0);p&&(l=!0,ne(o,p))};!n&&t.mixins.length&&t.mixins.forEach(u),e.extends&&u(e.extends),e.mixins&&e.mixins.forEach(u)}return!i&&!l?(W(e)&&s.set(e,null),null):(M(i)?i.forEach(u=>o[u]=null):ne(o,i),W(e)&&s.set(e,o),o)}function Zt(e,t){return!e||!qt(t)?!1:(t=t.slice(2).replace(/Once$/,""),S(e,t[0].toLowerCase()+t.slice(1))||S(e,Qe(t))||S(e,t))}let ae=null,Qt=null;function kt(e){const t=ae;return ae=e,Qt=e&&e.type.__scopeId||null,t}function Ri(e){Qt=e}function Li(){Qt=null}function Si(e,t=ae,n){if(!t||e._n)return e;const s=(...r)=>{s._d&&ys(-1);const i=kt(t);let o;try{o=e(...r)}finally{kt(i),s._d&&ys(1)}return o};return s._n=!0,s._c=!0,s._d=!0,s}function un(e){const{type:t,vnode:n,proxy:s,withProxy:r,props:i,propsOptions:[o],slots:l,attrs:u,emit:a,render:p,renderCache:x,data:C,setupState:O,ctx:H,inheritAttrs:P}=e;let $,F;const X=kt(e);try{if(n.shapeFlag&4){const k=r||s;$=Ee(p.call(k,k,x,i,O,C,H)),F=u}else{const k=t;$=Ee(k.length>1?k(i,{attrs:u,slots:l,emit:a}):k(i,null)),F=t.props?u:Ni(u)}}catch(k){yt.length=0,Xt(k,e,1),$=Me(xe)}let A=$;if(F&&P!==!1){const k=Object.keys(F),{shapeFlag:Q}=A;k.length&&Q&7&&(o&&k.some(Kn)&&(F=Hi(F,o)),A=Ue(A,F))}return n.dirs&&(A=Ue(A),A.dirs=A.dirs?A.dirs.concat(n.dirs):n.dirs),n.transition&&(A.transition=n.transition),$=A,kt(X),$}const Ni=e=>{let t;for(const n in e)(n==="class"||n==="style"||qt(n))&&((t||(t={}))[n]=e[n]);return t},Hi=(e,t)=>{const n={};for(const s in e)(!Kn(s)||!(s.slice(9)in t))&&(n[s]=e[s]);return n};function ji(e,t,n){const{props:s,children:r,component:i}=e,{props:o,children:l,patchFlag:u}=t,a=i.emitsOptions;if(t.dirs||t.transition)return!0;if(n&&u>=0){if(u&1024)return!0;if(u&16)return s?as(s,o,a):!!o;if(u&8){const p=t.dynamicProps;for(let x=0;xe.__isSuspense;function $i(e,t){t&&t.pendingBranch?M(e)?t.effects.push(...e):t.effects.push(e):Fi(e)}function Di(e,t){if(J){let n=J.provides;const s=J.parent&&J.parent.provides;s===n&&(n=J.provides=Object.create(s)),n[e]=t}}function Ht(e,t,n=!1){const s=J||ae;if(s){const r=s.parent==null?s.vnode.appContext&&s.vnode.appContext.provides:s.parent.provides;if(r&&e in r)return r[e];if(arguments.length>1)return n&&K(t)?t.call(s.proxy):t}}const Rt={};function jt(e,t,n){return cr(e,t,n)}function cr(e,t,{immediate:n,deep:s,flush:r,onTrack:i,onTrigger:o}=D){const l=Yr()===(J==null?void 0:J.scope)?J:null;let u,a=!1,p=!1;if(te(e)?(u=()=>e.value,a=Dt(e)):ot(e)?(u=()=>e,s=!0):M(e)?(p=!0,a=e.some(A=>ot(A)||Dt(A)),u=()=>e.map(A=>{if(te(A))return A.value;if(ot(A))return Ge(A);if(K(A))return je(A,l,2)})):K(e)?t?u=()=>je(e,l,2):u=()=>{if(!(l&&l.isUnmounted))return x&&x(),de(e,l,3,[C])}:u=ye,t&&s){const A=u;u=()=>Ge(A())}let x,C=A=>{x=F.onStop=()=>{je(A,l,4)}},O;if(Et)if(C=ye,t?n&&de(t,l,3,[u(),p?[]:void 0,C]):u(),r==="sync"){const A=$o();O=A.__watcherHandles||(A.__watcherHandles=[])}else return ye;let H=p?new Array(e.length).fill(Rt):Rt;const P=()=>{if(F.active)if(t){const A=F.run();(s||a||(p?A.some((k,Q)=>xt(k,H[Q])):xt(A,H)))&&(x&&x(),de(t,l,3,[A,H===Rt?void 0:p&&H[0]===Rt?[]:H,C]),H=A)}else F.run()};P.allowRecurse=!!t;let $;r==="sync"?$=P:r==="post"?$=()=>ie(P,l&&l.suspense):(P.pre=!0,l&&(P.id=l.uid),$=()=>Wn(P));const F=new Hn(u,$);t?n?P():H=F.run():r==="post"?ie(F.run.bind(F),l&&l.suspense):F.run();const X=()=>{F.stop(),l&&l.scope&&Rn(l.scope.effects,F)};return O&&O.push(X),X}function ki(e,t,n){const s=this.proxy,r=G(e)?e.includes(".")?fr(s,e):()=>s[e]:e.bind(s,s);let i;K(t)?i=t:(i=t.handler,n=t);const o=J;ut(this);const l=cr(r,i.bind(s),n);return o?ut(o):Ze(),l}function fr(e,t){const n=t.split(".");return()=>{let s=e;for(let r=0;r{Ge(n,t)});else if(Hs(e))for(const n in e)Ge(e[n],t);return e}function Wi(){const e={isMounted:!1,isLeaving:!1,isUnmounting:!1,leavingVNodes:new Map};return zn(()=>{e.isMounted=!0}),hr(()=>{e.isUnmounting=!0}),e}const fe=[Function,Array],zi={name:"BaseTransition",props:{mode:String,appear:Boolean,persisted:Boolean,onBeforeEnter:fe,onEnter:fe,onAfterEnter:fe,onEnterCancelled:fe,onBeforeLeave:fe,onLeave:fe,onAfterLeave:fe,onLeaveCancelled:fe,onBeforeAppear:fe,onAppear:fe,onAfterAppear:fe,onAppearCancelled:fe},setup(e,{slots:t}){const n=Lo(),s=Wi();let r;return()=>{const i=t.default&&ar(t.default(),!0);if(!i||!i.length)return;let o=i[0];if(i.length>1){for(const P of i)if(P.type!==xe){o=P;break}}const l=N(e),{mode:u}=l;if(s.isLeaving)return an(o);const a=ds(o);if(!a)return an(o);const p=wn(a,l,s,n);vn(a,p);const x=n.subTree,C=x&&ds(x);let O=!1;const{getTransitionKey:H}=a.type;if(H){const P=H();r===void 0?r=P:P!==r&&(r=P,O=!0)}if(C&&C.type!==xe&&(!Je(a,C)||O)){const P=wn(C,l,s,n);if(vn(C,P),u==="out-in")return s.isLeaving=!0,P.afterLeave=()=>{s.isLeaving=!1,n.update.active!==!1&&n.update()},an(o);u==="in-out"&&a.type!==xe&&(P.delayLeave=($,F,X)=>{const A=ur(s,C);A[String(C.key)]=C,$._leaveCb=()=>{F(),$._leaveCb=void 0,delete p.delayedLeave},p.delayedLeave=X})}return o}}},qi=zi;function ur(e,t){const{leavingVNodes:n}=e;let s=n.get(t.type);return s||(s=Object.create(null),n.set(t.type,s)),s}function wn(e,t,n,s){const{appear:r,mode:i,persisted:o=!1,onBeforeEnter:l,onEnter:u,onAfterEnter:a,onEnterCancelled:p,onBeforeLeave:x,onLeave:C,onAfterLeave:O,onLeaveCancelled:H,onBeforeAppear:P,onAppear:$,onAfterAppear:F,onAppearCancelled:X}=t,A=String(e.key),k=ur(n,e),Q=(R,Z)=>{R&&de(R,s,9,Z)},et=(R,Z)=>{const z=Z[1];Q(R,Z),M(R)?R.every(le=>le.length<=1)&&z():R.length<=1&&z()},Le={mode:i,persisted:o,beforeEnter(R){let Z=l;if(!n.isMounted)if(r)Z=P||l;else return;R._leaveCb&&R._leaveCb(!0);const z=k[A];z&&Je(e,z)&&z.el._leaveCb&&z.el._leaveCb(),Q(Z,[R])},enter(R){let Z=u,z=a,le=p;if(!n.isMounted)if(r)Z=$||u,z=F||a,le=X||p;else return;let Ce=!1;const Pe=R._enterCb=ht=>{Ce||(Ce=!0,ht?Q(le,[R]):Q(z,[R]),Le.delayedLeave&&Le.delayedLeave(),R._enterCb=void 0)};Z?et(Z,[R,Pe]):Pe()},leave(R,Z){const z=String(e.key);if(R._enterCb&&R._enterCb(!0),n.isUnmounting)return Z();Q(x,[R]);let le=!1;const Ce=R._leaveCb=Pe=>{le||(le=!0,Z(),Pe?Q(H,[R]):Q(O,[R]),R._leaveCb=void 0,k[z]===e&&delete k[z])};k[z]=e,C?et(C,[R,Ce]):Ce()},clone(R){return wn(R,t,n,s)}};return Le}function an(e){if(en(e))return e=Ue(e),e.children=null,e}function ds(e){return en(e)?e.children?e.children[0]:void 0:e}function vn(e,t){e.shapeFlag&6&&e.component?vn(e.component.subTree,t):e.shapeFlag&128?(e.ssContent.transition=t.clone(e.ssContent),e.ssFallback.transition=t.clone(e.ssFallback)):e.transition=t}function ar(e,t=!1,n){let s=[],r=0;for(let i=0;i1)for(let i=0;i!!e.type.__asyncLoader,en=e=>e.type.__isKeepAlive;function Ji(e,t){dr(e,"a",t)}function Vi(e,t){dr(e,"da",t)}function dr(e,t,n=J){const s=e.__wdc||(e.__wdc=()=>{let r=n;for(;r;){if(r.isDeactivated)return;r=r.parent}return e()});if(tn(t,s,n),n){let r=n.parent;for(;r&&r.parent;)en(r.parent.vnode)&&Gi(s,t,n,r),r=r.parent}}function Gi(e,t,n,s){const r=tn(t,e,s,!0);qn(()=>{Rn(s[t],r)},n)}function tn(e,t,n=J,s=!1){if(n){const r=n[e]||(n[e]=[]),i=t.__weh||(t.__weh=(...o)=>{if(n.isUnmounted)return;at(),ut(n);const l=de(t,n,e,o);return Ze(),dt(),l});return s?r.unshift(i):r.push(i),i}}const Re=e=>(t,n=J)=>(!Et||e==="sp")&&tn(e,(...s)=>t(...s),n),Xi=Re("bm"),zn=Re("m"),Zi=Re("bu"),Qi=Re("u"),hr=Re("bum"),qn=Re("um"),eo=Re("sp"),to=Re("rtg"),no=Re("rtc");function so(e,t=J){tn("ec",e,t)}function ro(e,t){const n=ae;if(n===null)return e;const s=rn(n)||n.proxy,r=e.dirs||(e.dirs=[]);for(let i=0;it(o,l,void 0,i&&i[l]));else{const o=Object.keys(e);r=new Array(o.length);for(let l=0,u=o.length;le?Tr(e)?rn(e)||e.proxy:Tn(e.parent):null,bt=ne(Object.create(null),{$:e=>e,$el:e=>e.vnode.el,$data:e=>e.data,$props:e=>e.props,$attrs:e=>e.attrs,$slots:e=>e.slots,$refs:e=>e.refs,$parent:e=>Tn(e.parent),$root:e=>Tn(e.root),$emit:e=>e.emit,$options:e=>Yn(e),$forceUpdate:e=>e.f||(e.f=()=>Wn(e.update)),$nextTick:e=>e.n||(e.n=Pi.bind(e.proxy)),$watch:e=>ki.bind(e)}),dn=(e,t)=>e!==D&&!e.__isScriptSetup&&S(e,t),lo={get({_:e},t){const{ctx:n,setupState:s,data:r,props:i,accessCache:o,type:l,appContext:u}=e;let a;if(t[0]!=="$"){const O=o[t];if(O!==void 0)switch(O){case 1:return s[t];case 2:return r[t];case 4:return n[t];case 3:return i[t]}else{if(dn(s,t))return o[t]=1,s[t];if(r!==D&&S(r,t))return o[t]=2,r[t];if((a=e.propsOptions[0])&&S(a,t))return o[t]=3,i[t];if(n!==D&&S(n,t))return o[t]=4,n[t];En&&(o[t]=0)}}const p=bt[t];let x,C;if(p)return t==="$attrs"&&oe(e,"get",t),p(e);if((x=l.__cssModules)&&(x=x[t]))return x;if(n!==D&&S(n,t))return o[t]=4,n[t];if(C=u.config.globalProperties,S(C,t))return C[t]},set({_:e},t,n){const{data:s,setupState:r,ctx:i}=e;return dn(r,t)?(r[t]=n,!0):s!==D&&S(s,t)?(s[t]=n,!0):S(e.props,t)||t[0]==="$"&&t.slice(1)in e?!1:(i[t]=n,!0)},has({_:{data:e,setupState:t,accessCache:n,ctx:s,appContext:r,propsOptions:i}},o){let l;return!!n[o]||e!==D&&S(e,o)||dn(t,o)||(l=i[0])&&S(l,o)||S(s,o)||S(bt,o)||S(r.config.globalProperties,o)},defineProperty(e,t,n){return n.get!=null?e._.accessCache[t]=0:S(n,"value")&&this.set(e,t,n.value,null),Reflect.defineProperty(e,t,n)}};let En=!0;function co(e){const t=Yn(e),n=e.proxy,s=e.ctx;En=!1,t.beforeCreate&&hs(t.beforeCreate,e,"bc");const{data:r,computed:i,methods:o,watch:l,provide:u,inject:a,created:p,beforeMount:x,mounted:C,beforeUpdate:O,updated:H,activated:P,deactivated:$,beforeDestroy:F,beforeUnmount:X,destroyed:A,unmounted:k,render:Q,renderTracked:et,renderTriggered:Le,errorCaptured:R,serverPrefetch:Z,expose:z,inheritAttrs:le,components:Ce,directives:Pe,filters:ht}=t;if(a&&fo(a,s,null,e.appContext.config.unwrapInjectedRef),o)for(const q in o){const B=o[q];K(B)&&(s[q]=B.bind(n))}if(r){const q=r.call(n,n);W(q)&&(e.data=Gt(q))}if(En=!0,i)for(const q in i){const B=i[q],$e=K(B)?B.bind(n,n):K(B.get)?B.get.bind(n,n):ye,At=!K(B)&&K(B.set)?B.set.bind(n):ye,De=Ar({get:$e,set:At});Object.defineProperty(s,q,{enumerable:!0,configurable:!0,get:()=>De.value,set:we=>De.value=we})}if(l)for(const q in l)pr(l[q],s,n,q);if(u){const q=K(u)?u.call(n):u;Reflect.ownKeys(q).forEach(B=>{Di(B,q[B])})}p&&hs(p,e,"c");function se(q,B){M(B)?B.forEach($e=>q($e.bind(n))):B&&q(B.bind(n))}if(se(Xi,x),se(zn,C),se(Zi,O),se(Qi,H),se(Ji,P),se(Vi,$),se(so,R),se(no,et),se(to,Le),se(hr,X),se(qn,k),se(eo,Z),M(z))if(z.length){const q=e.exposed||(e.exposed={});z.forEach(B=>{Object.defineProperty(q,B,{get:()=>n[B],set:$e=>n[B]=$e})})}else e.exposed||(e.exposed={});Q&&e.render===ye&&(e.render=Q),le!=null&&(e.inheritAttrs=le),Ce&&(e.components=Ce),Pe&&(e.directives=Pe)}function fo(e,t,n=ye,s=!1){M(e)&&(e=An(e));for(const r in e){const i=e[r];let o;W(i)?"default"in i?o=Ht(i.from||r,i.default,!0):o=Ht(i.from||r):o=Ht(i),te(o)&&s?Object.defineProperty(t,r,{enumerable:!0,configurable:!0,get:()=>o.value,set:l=>o.value=l}):t[r]=o}}function hs(e,t,n){de(M(e)?e.map(s=>s.bind(t.proxy)):e.bind(t.proxy),t,n)}function pr(e,t,n,s){const r=s.includes(".")?fr(n,s):()=>n[s];if(G(e)){const i=t[e];K(i)&&jt(r,i)}else if(K(e))jt(r,e.bind(n));else if(W(e))if(M(e))e.forEach(i=>pr(i,t,n,s));else{const i=K(e.handler)?e.handler.bind(n):t[e.handler];K(i)&&jt(r,i,e)}}function Yn(e){const t=e.type,{mixins:n,extends:s}=t,{mixins:r,optionsCache:i,config:{optionMergeStrategies:o}}=e.appContext,l=i.get(t);let u;return l?u=l:!r.length&&!n&&!s?u=t:(u={},r.length&&r.forEach(a=>Wt(u,a,o,!0)),Wt(u,t,o)),W(t)&&i.set(t,u),u}function Wt(e,t,n,s=!1){const{mixins:r,extends:i}=t;i&&Wt(e,i,n,!0),r&&r.forEach(o=>Wt(e,o,n,!0));for(const o in t)if(!(s&&o==="expose")){const l=uo[o]||n&&n[o];e[o]=l?l(e[o],t[o]):t[o]}return e}const uo={data:ps,props:qe,emits:qe,methods:qe,computed:qe,beforeCreate:re,created:re,beforeMount:re,mounted:re,beforeUpdate:re,updated:re,beforeDestroy:re,beforeUnmount:re,destroyed:re,unmounted:re,activated:re,deactivated:re,errorCaptured:re,serverPrefetch:re,components:qe,directives:qe,watch:ho,provide:ps,inject:ao};function ps(e,t){return t?e?function(){return ne(K(e)?e.call(this,this):e,K(t)?t.call(this,this):t)}:t:e}function ao(e,t){return qe(An(e),An(t))}function An(e){if(M(e)){const t={};for(let n=0;n0)&&!(o&16)){if(o&8){const p=e.vnode.dynamicProps;for(let x=0;x{u=!0;const[C,O]=mr(x,t,!0);ne(o,C),O&&l.push(...O)};!n&&t.mixins.length&&t.mixins.forEach(p),e.extends&&p(e.extends),e.mixins&&e.mixins.forEach(p)}if(!i&&!u)return W(e)&&s.set(e,rt),rt;if(M(i))for(let p=0;p-1,O[1]=P<0||H-1||S(O,"default"))&&l.push(x)}}}const a=[o,l];return W(e)&&s.set(e,a),a}function gs(e){return e[0]!=="$"}function ms(e){const t=e&&e.toString().match(/^\s*(function|class) (\w+)/);return t?t[2]:e===null?"null":""}function _s(e,t){return ms(e)===ms(t)}function bs(e,t){return M(t)?t.findIndex(n=>_s(n,e)):K(t)&&_s(t,e)?0:-1}const _r=e=>e[0]==="_"||e==="$stable",Jn=e=>M(e)?e.map(Ee):[Ee(e)],mo=(e,t,n)=>{if(t._n)return t;const s=Si((...r)=>Jn(t(...r)),n);return s._c=!1,s},br=(e,t,n)=>{const s=e._ctx;for(const r in e){if(_r(r))continue;const i=e[r];if(K(i))t[r]=mo(r,i,s);else if(i!=null){const o=Jn(i);t[r]=()=>o}}},yr=(e,t)=>{const n=Jn(t);e.slots.default=()=>n},_o=(e,t)=>{if(e.vnode.shapeFlag&32){const n=t._;n?(e.slots=N(t),$t(t,"_",n)):br(t,e.slots={})}else e.slots={},t&&yr(e,t);$t(e.slots,sn,1)},bo=(e,t,n)=>{const{vnode:s,slots:r}=e;let i=!0,o=D;if(s.shapeFlag&32){const l=t._;l?n&&l===1?i=!1:(ne(r,t),!n&&l===1&&delete r._):(i=!t.$stable,br(t,r)),o=t}else t&&(yr(e,t),o={default:1});if(i)for(const l in r)!_r(l)&&!(l in o)&&delete r[l]};function xr(){return{app:null,config:{isNativeTag:jr,performance:!1,globalProperties:{},optionMergeStrategies:{},errorHandler:void 0,warnHandler:void 0,compilerOptions:{}},mixins:[],components:{},directives:{},provides:Object.create(null),optionsCache:new WeakMap,propsCache:new WeakMap,emitsCache:new WeakMap}}let yo=0;function xo(e,t){return function(s,r=null){K(s)||(s=Object.assign({},s)),r!=null&&!W(r)&&(r=null);const i=xr(),o=new Set;let l=!1;const u=i.app={_uid:yo++,_component:s,_props:r,_container:null,_context:i,_instance:null,version:Do,get config(){return i.config},set config(a){},use(a,...p){return o.has(a)||(a&&K(a.install)?(o.add(a),a.install(u,...p)):K(a)&&(o.add(a),a(u,...p))),u},mixin(a){return i.mixins.includes(a)||i.mixins.push(a),u},component(a,p){return p?(i.components[a]=p,u):i.components[a]},directive(a,p){return p?(i.directives[a]=p,u):i.directives[a]},mount(a,p,x){if(!l){const C=Me(s,r);return C.appContext=i,p&&t?t(C,a):e(C,a,x),l=!0,u._container=a,a.__vue_app__=u,rn(C.component)||C.component.proxy}},unmount(){l&&(e(null,u._container),delete u._container.__vue_app__)},provide(a,p){return i.provides[a]=p,u}};return u}}function On(e,t,n,s,r=!1){if(M(e)){e.forEach((C,O)=>On(C,t&&(M(t)?t[O]:t),n,s,r));return}if(Bt(s)&&!r)return;const i=s.shapeFlag&4?rn(s.component)||s.component.proxy:s.el,o=r?null:i,{i:l,r:u}=e,a=t&&t.r,p=l.refs===D?l.refs={}:l.refs,x=l.setupState;if(a!=null&&a!==u&&(G(a)?(p[a]=null,S(x,a)&&(x[a]=null)):te(a)&&(a.value=null)),K(u))je(u,l,12,[o,p]);else{const C=G(u),O=te(u);if(C||O){const H=()=>{if(e.f){const P=C?S(x,u)?x[u]:p[u]:u.value;r?M(P)&&Rn(P,i):M(P)?P.includes(i)||P.push(i):C?(p[u]=[i],S(x,u)&&(x[u]=p[u])):(u.value=[i],e.k&&(p[e.k]=u.value))}else C?(p[u]=o,S(x,u)&&(x[u]=o)):O&&(u.value=o,e.k&&(p[e.k]=o))};o?(H.id=-1,ie(H,n)):H()}}}const ie=$i;function Co(e){return wo(e)}function wo(e,t){const n=Wr();n.__VUE__=!0;const{insert:s,remove:r,patchProp:i,createElement:o,createText:l,createComment:u,setText:a,setElementText:p,parentNode:x,nextSibling:C,setScopeId:O=ye,insertStaticContent:H}=e,P=(c,f,d,g=null,h=null,b=null,w=!1,_=null,y=!!f.dynamicChildren)=>{if(c===f)return;c&&!Je(c,f)&&(g=Pt(c),we(c,h,b,!0),c=null),f.patchFlag===-2&&(y=!1,f.dynamicChildren=null);const{type:m,ref:T,shapeFlag:v}=f;switch(m){case nn:$(c,f,d,g);break;case xe:F(c,f,d,g);break;case hn:c==null&&X(f,d,g,w);break;case me:Ce(c,f,d,g,h,b,w,_,y);break;default:v&1?Q(c,f,d,g,h,b,w,_,y):v&6?Pe(c,f,d,g,h,b,w,_,y):(v&64||v&128)&&m.process(c,f,d,g,h,b,w,_,y,tt)}T!=null&&h&&On(T,c&&c.ref,b,f||c,!f)},$=(c,f,d,g)=>{if(c==null)s(f.el=l(f.children),d,g);else{const h=f.el=c.el;f.children!==c.children&&a(h,f.children)}},F=(c,f,d,g)=>{c==null?s(f.el=u(f.children||""),d,g):f.el=c.el},X=(c,f,d,g)=>{[c.el,c.anchor]=H(c.children,f,d,g,c.el,c.anchor)},A=({el:c,anchor:f},d,g)=>{let h;for(;c&&c!==f;)h=C(c),s(c,d,g),c=h;s(f,d,g)},k=({el:c,anchor:f})=>{let d;for(;c&&c!==f;)d=C(c),r(c),c=d;r(f)},Q=(c,f,d,g,h,b,w,_,y)=>{w=w||f.type==="svg",c==null?et(f,d,g,h,b,w,_,y):Z(c,f,h,b,w,_,y)},et=(c,f,d,g,h,b,w,_)=>{let y,m;const{type:T,props:v,shapeFlag:E,transition:I,dirs:L}=c;if(y=c.el=o(c.type,b,v&&v.is,v),E&8?p(y,c.children):E&16&&R(c.children,y,null,g,h,b&&T!=="foreignObject",w,_),L&&We(c,null,g,"created"),Le(y,c,c.scopeId,w,g),v){for(const j in v)j!=="value"&&!St(j)&&i(y,j,null,v[j],b,c.children,g,h,Oe);"value"in v&&i(y,"value",null,v.value),(m=v.onVnodeBeforeMount)&&Te(m,g,c)}L&&We(c,null,g,"beforeMount");const U=(!h||h&&!h.pendingBranch)&&I&&!I.persisted;U&&I.beforeEnter(y),s(y,f,d),((m=v&&v.onVnodeMounted)||U||L)&&ie(()=>{m&&Te(m,g,c),U&&I.enter(y),L&&We(c,null,g,"mounted")},h)},Le=(c,f,d,g,h)=>{if(d&&O(c,d),g)for(let b=0;b{for(let m=y;m{const _=f.el=c.el;let{patchFlag:y,dynamicChildren:m,dirs:T}=f;y|=c.patchFlag&16;const v=c.props||D,E=f.props||D;let I;d&&ze(d,!1),(I=E.onVnodeBeforeUpdate)&&Te(I,d,f,c),T&&We(f,c,d,"beforeUpdate"),d&&ze(d,!0);const L=h&&f.type!=="foreignObject";if(m?z(c.dynamicChildren,m,_,d,g,L,b):w||B(c,f,_,null,d,g,L,b,!1),y>0){if(y&16)le(_,f,v,E,d,g,h);else if(y&2&&v.class!==E.class&&i(_,"class",null,E.class,h),y&4&&i(_,"style",v.style,E.style,h),y&8){const U=f.dynamicProps;for(let j=0;j{I&&Te(I,d,f,c),T&&We(f,c,d,"updated")},g)},z=(c,f,d,g,h,b,w)=>{for(let _=0;_{if(d!==g){if(d!==D)for(const _ in d)!St(_)&&!(_ in g)&&i(c,_,d[_],null,w,f.children,h,b,Oe);for(const _ in g){if(St(_))continue;const y=g[_],m=d[_];y!==m&&_!=="value"&&i(c,_,m,y,w,f.children,h,b,Oe)}"value"in g&&i(c,"value",d.value,g.value)}},Ce=(c,f,d,g,h,b,w,_,y)=>{const m=f.el=c?c.el:l(""),T=f.anchor=c?c.anchor:l("");let{patchFlag:v,dynamicChildren:E,slotScopeIds:I}=f;I&&(_=_?_.concat(I):I),c==null?(s(m,d,g),s(T,d,g),R(f.children,d,T,h,b,w,_,y)):v>0&&v&64&&E&&c.dynamicChildren?(z(c.dynamicChildren,E,d,h,b,w,_),(f.key!=null||h&&f===h.subTree)&&Cr(c,f,!0)):B(c,f,d,T,h,b,w,_,y)},Pe=(c,f,d,g,h,b,w,_,y)=>{f.slotScopeIds=_,c==null?f.shapeFlag&512?h.ctx.activate(f,d,g,w,y):ht(f,d,g,h,b,w,y):Gn(c,f,y)},ht=(c,f,d,g,h,b,w)=>{const _=c.component=Ro(c,g,h);if(en(c)&&(_.ctx.renderer=tt),So(_),_.asyncDep){if(h&&h.registerDep(_,se),!c.el){const y=_.subTree=Me(xe);F(null,y,f,d)}return}se(_,c,f,d,h,b,w)},Gn=(c,f,d)=>{const g=f.component=c.component;if(ji(c,f,d))if(g.asyncDep&&!g.asyncResolved){q(g,f,d);return}else g.next=f,Ii(g.update),g.update();else f.el=c.el,g.vnode=f},se=(c,f,d,g,h,b,w)=>{const _=()=>{if(c.isMounted){let{next:T,bu:v,u:E,parent:I,vnode:L}=c,U=T,j;ze(c,!1),T?(T.el=L.el,q(c,T,w)):T=L,v&&Nt(v),(j=T.props&&T.props.onVnodeBeforeUpdate)&&Te(j,I,T,L),ze(c,!0);const Y=un(c),he=c.subTree;c.subTree=Y,P(he,Y,x(he.el),Pt(he),c,h,b),T.el=Y.el,U===null&&Bi(c,Y.el),E&&ie(E,h),(j=T.props&&T.props.onVnodeUpdated)&&ie(()=>Te(j,I,T,L),h)}else{let T;const{el:v,props:E}=f,{bm:I,m:L,parent:U}=c,j=Bt(f);if(ze(c,!1),I&&Nt(I),!j&&(T=E&&E.onVnodeBeforeMount)&&Te(T,U,f),ze(c,!0),v&&ln){const Y=()=>{c.subTree=un(c),ln(v,c.subTree,c,h,null)};j?f.type.__asyncLoader().then(()=>!c.isUnmounted&&Y()):Y()}else{const Y=c.subTree=un(c);P(null,Y,d,g,c,h,b),f.el=Y.el}if(L&&ie(L,h),!j&&(T=E&&E.onVnodeMounted)){const Y=f;ie(()=>Te(T,U,Y),h)}(f.shapeFlag&256||U&&Bt(U.vnode)&&U.vnode.shapeFlag&256)&&c.a&&ie(c.a,h),c.isMounted=!0,f=d=g=null}},y=c.effect=new Hn(_,()=>Wn(m),c.scope),m=c.update=()=>y.run();m.id=c.uid,ze(c,!0),m()},q=(c,f,d)=>{f.component=c;const g=c.vnode.props;c.vnode=f,c.next=null,go(c,f.props,g,d),bo(c,f.children,d),at(),us(),dt()},B=(c,f,d,g,h,b,w,_,y=!1)=>{const m=c&&c.children,T=c?c.shapeFlag:0,v=f.children,{patchFlag:E,shapeFlag:I}=f;if(E>0){if(E&128){At(m,v,d,g,h,b,w,_,y);return}else if(E&256){$e(m,v,d,g,h,b,w,_,y);return}}I&8?(T&16&&Oe(m,h,b),v!==m&&p(d,v)):T&16?I&16?At(m,v,d,g,h,b,w,_,y):Oe(m,h,b,!0):(T&8&&p(d,""),I&16&&R(v,d,g,h,b,w,_,y))},$e=(c,f,d,g,h,b,w,_,y)=>{c=c||rt,f=f||rt;const m=c.length,T=f.length,v=Math.min(m,T);let E;for(E=0;ET?Oe(c,h,b,!0,!1,v):R(f,d,g,h,b,w,_,y,v)},At=(c,f,d,g,h,b,w,_,y)=>{let m=0;const T=f.length;let v=c.length-1,E=T-1;for(;m<=v&&m<=E;){const I=c[m],L=f[m]=y?Ne(f[m]):Ee(f[m]);if(Je(I,L))P(I,L,d,null,h,b,w,_,y);else break;m++}for(;m<=v&&m<=E;){const I=c[v],L=f[E]=y?Ne(f[E]):Ee(f[E]);if(Je(I,L))P(I,L,d,null,h,b,w,_,y);else break;v--,E--}if(m>v){if(m<=E){const I=E+1,L=IE)for(;m<=v;)we(c[m],h,b,!0),m++;else{const I=m,L=m,U=new Map;for(m=L;m<=E;m++){const ce=f[m]=y?Ne(f[m]):Ee(f[m]);ce.key!=null&&U.set(ce.key,m)}let j,Y=0;const he=E-L+1;let nt=!1,Qn=0;const pt=new Array(he);for(m=0;m=he){we(ce,h,b,!0);continue}let ve;if(ce.key!=null)ve=U.get(ce.key);else for(j=L;j<=E;j++)if(pt[j-L]===0&&Je(ce,f[j])){ve=j;break}ve===void 0?we(ce,h,b,!0):(pt[ve-L]=m+1,ve>=Qn?Qn=ve:nt=!0,P(ce,f[ve],d,null,h,b,w,_,y),Y++)}const es=nt?vo(pt):rt;for(j=es.length-1,m=he-1;m>=0;m--){const ce=L+m,ve=f[ce],ts=ce+1{const{el:b,type:w,transition:_,children:y,shapeFlag:m}=c;if(m&6){De(c.component.subTree,f,d,g);return}if(m&128){c.suspense.move(f,d,g);return}if(m&64){w.move(c,f,d,tt);return}if(w===me){s(b,f,d);for(let v=0;v_.enter(b),h);else{const{leave:v,delayLeave:E,afterLeave:I}=_,L=()=>s(b,f,d),U=()=>{v(b,()=>{L(),I&&I()})};E?E(b,L,U):U()}else s(b,f,d)},we=(c,f,d,g=!1,h=!1)=>{const{type:b,props:w,ref:_,children:y,dynamicChildren:m,shapeFlag:T,patchFlag:v,dirs:E}=c;if(_!=null&&On(_,null,d,c,!0),T&256){f.ctx.deactivate(c);return}const I=T&1&&E,L=!Bt(c);let U;if(L&&(U=w&&w.onVnodeBeforeUnmount)&&Te(U,f,c),T&6)Ir(c.component,d,g);else{if(T&128){c.suspense.unmount(d,g);return}I&&We(c,null,f,"beforeUnmount"),T&64?c.type.remove(c,f,d,h,tt,g):m&&(b!==me||v>0&&v&64)?Oe(m,f,d,!1,!0):(b===me&&v&384||!h&&T&16)&&Oe(y,f,d),g&&Xn(c)}(L&&(U=w&&w.onVnodeUnmounted)||I)&&ie(()=>{U&&Te(U,f,c),I&&We(c,null,f,"unmounted")},d)},Xn=c=>{const{type:f,el:d,anchor:g,transition:h}=c;if(f===me){Or(d,g);return}if(f===hn){k(c);return}const b=()=>{r(d),h&&!h.persisted&&h.afterLeave&&h.afterLeave()};if(c.shapeFlag&1&&h&&!h.persisted){const{leave:w,delayLeave:_}=h,y=()=>w(d,b);_?_(c.el,b,y):y()}else b()},Or=(c,f)=>{let d;for(;c!==f;)d=C(c),r(c),c=d;r(f)},Ir=(c,f,d)=>{const{bum:g,scope:h,update:b,subTree:w,um:_}=c;g&&Nt(g),h.stop(),b&&(b.active=!1,we(w,c,f,d)),_&&ie(_,f),ie(()=>{c.isUnmounted=!0},f),f&&f.pendingBranch&&!f.isUnmounted&&c.asyncDep&&!c.asyncResolved&&c.suspenseId===f.pendingId&&(f.deps--,f.deps===0&&f.resolve())},Oe=(c,f,d,g=!1,h=!1,b=0)=>{for(let w=b;wc.shapeFlag&6?Pt(c.component.subTree):c.shapeFlag&128?c.suspense.next():C(c.anchor||c.el),Zn=(c,f,d)=>{c==null?f._vnode&&we(f._vnode,null,null,!0):P(f._vnode||null,c,f,null,null,null,d),us(),ir(),f._vnode=c},tt={p:P,um:we,m:De,r:Xn,mt:ht,mc:R,pc:B,pbc:z,n:Pt,o:e};let on,ln;return t&&([on,ln]=t(tt)),{render:Zn,hydrate:on,createApp:xo(Zn,on)}}function ze({effect:e,update:t},n){e.allowRecurse=t.allowRecurse=n}function Cr(e,t,n=!1){const s=e.children,r=t.children;if(M(s)&&M(r))for(let i=0;i>1,e[n[l]]0&&(t[s]=n[i-1]),n[i]=s)}}for(i=n.length,o=n[i-1];i-- >0;)n[i]=o,o=t[o];return n}const To=e=>e.__isTeleport,me=Symbol(void 0),nn=Symbol(void 0),xe=Symbol(void 0),hn=Symbol(void 0),yt=[];let be=null;function ue(e=!1){yt.push(be=e?null:[])}function Eo(){yt.pop(),be=yt[yt.length-1]||null}let Tt=1;function ys(e){Tt+=e}function wr(e){return e.dynamicChildren=Tt>0?be||rt:null,Eo(),Tt>0&&be&&be.push(e),e}function pe(e,t,n,s,r,i){return wr(V(e,t,n,s,r,i,!0))}function Ao(e,t,n,s,r){return wr(Me(e,t,n,s,r,!0))}function Po(e){return e?e.__v_isVNode===!0:!1}function Je(e,t){return e.type===t.type&&e.key===t.key}const sn="__vInternal",vr=({key:e})=>e??null,Ut=({ref:e,ref_key:t,ref_for:n})=>e!=null?G(e)||te(e)||K(e)?{i:ae,r:e,k:t,f:!!n}:e:null;function V(e,t=null,n=null,s=0,r=null,i=e===me?0:1,o=!1,l=!1){const u={__v_isVNode:!0,__v_skip:!0,type:e,props:t,key:t&&vr(t),ref:t&&Ut(t),scopeId:Qt,slotScopeIds:null,children:n,component:null,suspense:null,ssContent:null,ssFallback:null,dirs:null,transition:null,el:null,anchor:null,target:null,targetAnchor:null,staticCount:0,shapeFlag:i,patchFlag:s,dynamicProps:r,dynamicChildren:null,appContext:null,ctx:ae};return l?(Vn(u,n),i&128&&e.normalize(u)):n&&(u.shapeFlag|=G(n)?8:16),Tt>0&&!o&&be&&(u.patchFlag>0||i&6)&&u.patchFlag!==32&&be.push(u),u}const Me=Oo;function Oo(e,t=null,n=null,s=0,r=null,i=!1){if((!e||e===io)&&(e=xe),Po(e)){const l=Ue(e,t,!0);return n&&Vn(l,n),Tt>0&&!i&&be&&(l.shapeFlag&6?be[be.indexOf(e)]=l:be.push(l)),l.patchFlag|=-2,l}if(Bo(e)&&(e=e.__vccOpts),t){t=Io(t);let{class:l,style:u}=t;l&&!G(l)&&(t.class=Mn(l)),W(u)&&(Gs(u)&&!M(u)&&(u=ne({},u)),t.style=zt(u))}const o=G(e)?1:Ui(e)?128:To(e)?64:W(e)?4:K(e)?2:0;return V(e,t,n,s,r,o,i,!0)}function Io(e){return e?Gs(e)||sn in e?ne({},e):e:null}function Ue(e,t,n=!1){const{props:s,ref:r,patchFlag:i,children:o}=e,l=t?Fo(s||{},t):s;return{__v_isVNode:!0,__v_skip:!0,type:e.type,props:l,key:l&&vr(l),ref:t&&t.ref?n&&r?M(r)?r.concat(Ut(t)):[r,Ut(t)]:Ut(t):r,scopeId:e.scopeId,slotScopeIds:e.slotScopeIds,children:o,target:e.target,targetAnchor:e.targetAnchor,staticCount:e.staticCount,shapeFlag:e.shapeFlag,patchFlag:t&&e.type!==me?i===-1?16:i|16:i,dynamicProps:e.dynamicProps,dynamicChildren:e.dynamicChildren,appContext:e.appContext,dirs:e.dirs,transition:e.transition,component:e.component,suspense:e.suspense,ssContent:e.ssContent&&Ue(e.ssContent),ssFallback:e.ssFallback&&Ue(e.ssFallback),el:e.el,anchor:e.anchor,ctx:e.ctx,ce:e.ce}}function Ie(e=" ",t=0){return Me(nn,null,e,t)}function Lt(e="",t=!1){return t?(ue(),Ao(xe,null,e)):Me(xe,null,e)}function Ee(e){return e==null||typeof e=="boolean"?Me(xe):M(e)?Me(me,null,e.slice()):typeof e=="object"?Ne(e):Me(nn,null,String(e))}function Ne(e){return e.el===null&&e.patchFlag!==-1||e.memo?e:Ue(e)}function Vn(e,t){let n=0;const{shapeFlag:s}=e;if(t==null)t=null;else if(M(t))n=16;else if(typeof t=="object")if(s&65){const r=t.default;r&&(r._c&&(r._d=!1),Vn(e,r()),r._c&&(r._d=!0));return}else{n=32;const r=t._;!r&&!(sn in t)?t._ctx=ae:r===3&&ae&&(ae.slots._===1?t._=1:(t._=2,e.patchFlag|=1024))}else K(t)?(t={default:t,_ctx:ae},n=32):(t=String(t),s&64?(n=16,t=[Ie(t)]):n=8);e.children=t,e.shapeFlag|=n}function Fo(...e){const t={};for(let n=0;nJ||ae,ut=e=>{J=e,e.scope.on()},Ze=()=>{J&&J.scope.off(),J=null};function Tr(e){return e.vnode.shapeFlag&4}let Et=!1;function So(e,t=!1){Et=t;const{props:n,children:s}=e.vnode,r=Tr(e);po(e,n,r,t),_o(e,s);const i=r?No(e,t):void 0;return Et=!1,i}function No(e,t){const n=e.type;e.accessCache=Object.create(null),e.proxy=Xs(new Proxy(e.ctx,lo));const{setup:s}=n;if(s){const r=e.setupContext=s.length>1?jo(e):null;ut(e),at();const i=je(s,e,0,[e.props,r]);if(dt(),Ze(),Ss(i)){if(i.then(Ze,Ze),t)return i.then(o=>{xs(e,o,t)}).catch(o=>{Xt(o,e,0)});e.asyncDep=i}else xs(e,i,t)}else Er(e,t)}function xs(e,t,n){K(t)?e.type.__ssrInlineRender?e.ssrRender=t:e.render=t:W(t)&&(e.setupState=tr(t)),Er(e,n)}let Cs;function Er(e,t,n){const s=e.type;if(!e.render){if(!t&&Cs&&!s.render){const r=s.template||Yn(e).template;if(r){const{isCustomElement:i,compilerOptions:o}=e.appContext.config,{delimiters:l,compilerOptions:u}=s,a=ne(ne({isCustomElement:i,delimiters:l},o),u);s.render=Cs(r,a)}}e.render=s.render||ye}ut(e),at(),co(e),dt(),Ze()}function Ho(e){return new Proxy(e.attrs,{get(t,n){return oe(e,"get","$attrs"),t[n]}})}function jo(e){const t=s=>{e.exposed=s||{}};let n;return{get attrs(){return n||(n=Ho(e))},slots:e.slots,emit:e.emit,expose:t}}function rn(e){if(e.exposed)return e.exposeProxy||(e.exposeProxy=new Proxy(tr(Xs(e.exposed)),{get(t,n){if(n in t)return t[n];if(n in bt)return bt[n](e)},has(t,n){return n in t||n in bt}}))}function Bo(e){return K(e)&&"__vccOpts"in e}const Ar=(e,t)=>Ei(e,t,Et),Uo=Symbol(""),$o=()=>Ht(Uo),Do="3.2.47",ko="http://www.w3.org/2000/svg",Ve=typeof document<"u"?document:null,ws=Ve&&Ve.createElement("template"),Wo={insert:(e,t,n)=>{t.insertBefore(e,n||null)},remove:e=>{const t=e.parentNode;t&&t.removeChild(e)},createElement:(e,t,n,s)=>{const r=t?Ve.createElementNS(ko,e):Ve.createElement(e,n?{is:n}:void 0);return e==="select"&&s&&s.multiple!=null&&r.setAttribute("multiple",s.multiple),r},createText:e=>Ve.createTextNode(e),createComment:e=>Ve.createComment(e),setText:(e,t)=>{e.nodeValue=t},setElementText:(e,t)=>{e.textContent=t},parentNode:e=>e.parentNode,nextSibling:e=>e.nextSibling,querySelector:e=>Ve.querySelector(e),setScopeId(e,t){e.setAttribute(t,"")},insertStaticContent(e,t,n,s,r,i){const o=n?n.previousSibling:t.lastChild;if(r&&(r===i||r.nextSibling))for(;t.insertBefore(r.cloneNode(!0),n),!(r===i||!(r=r.nextSibling)););else{ws.innerHTML=s?`${e}`:e;const l=ws.content;if(s){const u=l.firstChild;for(;u.firstChild;)l.appendChild(u.firstChild);l.removeChild(u)}t.insertBefore(l,n)}return[o?o.nextSibling:t.firstChild,n?n.previousSibling:t.lastChild]}};function zo(e,t,n){const s=e._vtc;s&&(t=(t?[t,...s]:[...s]).join(" ")),t==null?e.removeAttribute("class"):n?e.setAttribute("class",t):e.className=t}function qo(e,t,n){const s=e.style,r=G(n);if(n&&!r){if(t&&!G(t))for(const i in t)n[i]==null&&In(s,i,"");for(const i in n)In(s,i,n[i])}else{const i=s.display;r?t!==n&&(s.cssText=n):t&&e.removeAttribute("style"),"_vod"in e&&(s.display=i)}}const vs=/\s*!important$/;function In(e,t,n){if(M(n))n.forEach(s=>In(e,t,s));else if(n==null&&(n=""),t.startsWith("--"))e.setProperty(t,n);else{const s=Yo(e,t);vs.test(n)?e.setProperty(Qe(s),n.replace(vs,""),"important"):e[s]=n}}const Ts=["Webkit","Moz","ms"],pn={};function Yo(e,t){const n=pn[t];if(n)return n;let s=ct(t);if(s!=="filter"&&s in e)return pn[t]=s;s=js(s);for(let r=0;rgn||(Qo.then(()=>gn=0),gn=Date.now());function tl(e,t){const n=s=>{if(!s._vts)s._vts=Date.now();else if(s._vts<=n.attached)return;de(nl(s,n.value),t,5,[s])};return n.value=e,n.attached=el(),n}function nl(e,t){if(M(t)){const n=e.stopImmediatePropagation;return e.stopImmediatePropagation=()=>{n.call(e),e._stopped=!0},t.map(s=>r=>!r._stopped&&s&&s(r))}else return t}const Ps=/^on[a-z]/,sl=(e,t,n,s,r=!1,i,o,l,u)=>{t==="class"?zo(e,s,r):t==="style"?qo(e,n,s):qt(t)?Kn(t)||Xo(e,t,n,s,o):(t[0]==="."?(t=t.slice(1),!0):t[0]==="^"?(t=t.slice(1),!1):rl(e,t,s,r))?Vo(e,t,s,i,o,l,u):(t==="true-value"?e._trueValue=s:t==="false-value"&&(e._falseValue=s),Jo(e,t,s,r))};function rl(e,t,n,s){return s?!!(t==="innerHTML"||t==="textContent"||t in e&&Ps.test(t)&&K(n)):t==="spellcheck"||t==="draggable"||t==="translate"||t==="form"||t==="list"&&e.tagName==="INPUT"||t==="type"&&e.tagName==="TEXTAREA"||Ps.test(t)&&G(n)?!1:t in e}const il={name:String,type:String,css:{type:Boolean,default:!0},duration:[String,Number,Object],enterFromClass:String,enterActiveClass:String,enterToClass:String,appearFromClass:String,appearActiveClass:String,appearToClass:String,leaveFromClass:String,leaveActiveClass:String,leaveToClass:String};qi.props;const Os=e=>{const t=e.props["onUpdate:modelValue"]||!1;return M(t)?n=>Nt(t,n):t};function ol(e){e.target.composing=!0}function Is(e){const t=e.target;t.composing&&(t.composing=!1,t.dispatchEvent(new Event("input")))}const ll={created(e,{modifiers:{lazy:t,trim:n,number:s}},r){e._assign=Os(r);const i=s||r.props&&r.props.type==="number";st(e,t?"change":"input",o=>{if(o.target.composing)return;let l=e.value;n&&(l=l.trim()),i&&(l=mn(l)),e._assign(l)}),n&&st(e,"change",()=>{e.value=e.value.trim()}),t||(st(e,"compositionstart",ol),st(e,"compositionend",Is),st(e,"change",Is))},mounted(e,{value:t}){e.value=t??""},beforeUpdate(e,{value:t,modifiers:{lazy:n,trim:s,number:r}},i){if(e._assign=Os(i),e.composing||document.activeElement===e&&e.type!=="range"&&(n||s&&e.value.trim()===t||(r||e.type==="number")&&mn(e.value)===t))return;const o=t??"";e.value!==o&&(e.value=o)}},cl={esc:"escape",space:" ",up:"arrow-up",left:"arrow-left",right:"arrow-right",down:"arrow-down",delete:"backspace"},fl=(e,t)=>n=>{if(!("key"in n))return;const s=Qe(n.key);if(t.some(r=>r===s||cl[r]===s))return e(n)},ul=ne({patchProp:sl},Wo);let Fs;function al(){return Fs||(Fs=Co(ul))}const dl=(...e)=>{const t=al().createApp(...e),{mount:n}=t;return t.mount=s=>{const r=hl(s);if(!r)return;const i=t._component;!K(i)&&!i.render&&!i.template&&(i.template=r.innerHTML),r.innerHTML="";const o=n(r,!1,r instanceof SVGElement);return r instanceof Element&&(r.removeAttribute("v-cloak"),r.setAttribute("data-v-app","")),o},t};function hl(e){return G(e)?document.querySelector(e):e}const mt=Gt({apiKey:null});function pl(){const e="me.kingcos.chatgpd.apikey";return mt.apiKey=localStorage.getItem(e),jt(()=>mt.apiKey,s=>{mt.apiKey=s,s?localStorage.setItem(e,s):localStorage.removeItem(e)}),{getApiKey:()=>mt.apiKey,setApiKey:s=>{mt.apiKey=s}}}class Ms{constructor(t){gt(this,"apiKey");gt(this,"historyList",[]);gt(this,"dateFormatter",new Intl.DateTimeFormat("en-US",{year:"numeric",month:"2-digit",day:"2-digit"}));gt(this,"basePrompt",`You are ChatGPT, a large language model trained by OpenAI. Respond conversationally. Do not answer as the user. Current date: ${this.dateFormatter.format(new Date)} 2 | 3 | User: Hello 4 | ChatGPT: Hello! How can I help you today? 5 | 6 | 7 | `);this.apiKey=t}get urlRequest(){const t="https://api.openai.com/v1/completions";return new Request(t)}generateChatGPTPrompt(t){let n=`${this.basePrompt}${this.historyList.join("")}User: ${t} 8 | ChatGPT:`;return n.length>4e3*4&&(this.historyList.shift(),n=this.generateChatGPTPrompt(t)),n}async jsonBody(t,n=!0){const s={model:"text-davinci-003",temperature:.5,max_tokens:1024,prompt:this.generateChatGPTPrompt(t),stop:[` 9 | 10 | 11 | `,"<|im_end|>"],stream:n},r=await fetch(this.urlRequest,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.apiKey}`},body:JSON.stringify(s)});if(r.ok){const o=(await r.text()).trim().split(` 12 | `);let l="";for(let u=0;u(Ri("data-v-d52f4355"),e=e(),Li(),e),gl={class:"chatgkd"},ml=Pr(()=>V("div",{class:"title-container"},[V("span",{class:"title"},"ChatGKD"),V("a",{class:"subtitle",href:"https://github.com/kingcos/ChatGKD"},"Powered by kingcos.me")],-1)),_l={key:0,class:"help"},bl=Pr(()=>V("div",null,[Ie(" 1. 欢迎使用 ChatGKD for web,本项目已开源在 "),V("a",{href:"https://github.com/kingcos/ChatGKD"},"github.com/kingcos/ChatGKD"),Ie(";"),V("br"),Ie(" 2. ChatGKD for web 仅做接口封装与页面展示,不提供 API Key 且不对 OpenAI 内容负责,请自行申请使用并对内容负责;"),V("br"),Ie(" 3. API Key 将只保存在浏览器本地存储,不会做上传或其他操作;"),V("br"),Ie(" 4. 请按照格式「key:YOUR_API_KEY」格式输入,即可更新 API Key;"),V("br"),Ie(" 5. 请输入「登出」即可清除本地存储的 API Key;"),V("br"),Ie(" 6. 点击「新对话」将清除本次历史对话,并重新开启上下文对话。"),V("br"),V("br"),Ie(" 关注作者公众号「萌面大道」,更多好玩不迷路~ ")],-1)),yl=[bl],xl={key:1,class:"list"},Cl={key:0,class:"tips"},wl={key:0},vl={key:1},Tl={key:2},El={key:3,class:"human-text"},Al=["placeholder","disabled","onKeydown"],Pl=Yi({__name:"App",setup(e){const{getApiKey:t,setApiKey:n}=pl(),s=ke(!1),r=ke(""),i=ke([]),o=ke(""),l=ke(!1),u=ke(new Ms(""));function a(){const F=t();F!=null&&F.length>0&&(u.value=new Ms(F))}a();function p(){s.value=!s.value}function x(){i.value=[],a()}function C(){const F=o.value.trim();if(o.value="",F.startsWith("key:")){const A=F.replace("key:","");n(A),a(),r.value="API Key 已更新。";return}if(F=="登出"){r.value="API Key 已清空。",n("");return}const X=t();if(X==null||X.length==0){r.value="请先按照格式「key:YOUR_API_KEY」格式输入以更新 API Key。";return}r.value="",l.value?o.value=F:F&&(l.value=!0,i.value.push({isGPT:!1,message:F}),i.value.push({isGPT:!0,message:"💭 思考中..."}),u.value.sendMessageStream(F).then(A=>{l.value=!1,i.value[i.value.length-1].message=A.trim()}).catch(A=>{l.value=!1,i.value[i.value.length-1]={isGPT:!0,message:`[出错咯]${A}`}}))}function O(){l.value=!1}const H=Ar(()=>l.value?"💭 思考中...":"请在此输入消息..."),P=ke(0);function $(F){F.type==="show"?P.value=F.height:F.type==="hide"&&(P.value=0)}return zn(()=>{window.addEventListener("keyboardWillShow",$),window.addEventListener("keyboardWillHide",$)}),qn(()=>{window.removeEventListener("keyboardWillShow",$),window.removeEventListener("keyboardWillHide",$)}),(F,X)=>(ue(),pe("div",gl,[V("div",{class:"header"},[V("span",{class:"button",onClick:p},"帮助"),ml,V("span",{class:"button",onClick:x},"新对话")]),s.value?(ue(),pe("div",_l,yl)):Lt("",!0),i.value.length>0||r.value?(ue(),pe("div",xl,[r.value?(ue(),pe("div",Cl,cn(r.value),1)):Lt("",!0),(ue(!0),pe(me,null,oo(i.value,(A,k)=>(ue(),pe("div",{key:k,class:"item"},[A.isGPT?(ue(),pe("span",wl,"🤖️:")):(ue(),pe("span",vl,"🧑:")),A.isGPT?(ue(),pe("span",Tl,cn(A.message),1)):(ue(),pe("span",El,cn(A.message),1))]))),128))])):Lt("",!0),V("div",{class:"footer",style:zt({bottom:P.value+"px"})},[ro(V("input",{type:"text","onUpdate:modelValue":X[0]||(X[0]=A=>o.value=A),placeholder:er(H),disabled:l.value,onKeydown:fl(C,["enter"])},null,40,Al),[[ll,o.value]]),l.value?(ue(),pe("button",{key:0,class:"footer-button",onClick:O},"🛑")):Lt("",!0)],4)]))}});const Ol=(e,t)=>{const n=e.__vccOpts||e;for(const[s,r]of t)n[s]=r;return n},Il=Ol(Pl,[["__scopeId","data-v-d52f4355"]]);dl(Il).mount("#app"); 17 | -------------------------------------------------------------------------------- /web/assets/index-f97c6ee6.css: -------------------------------------------------------------------------------- 1 | body[data-v-d52f4355]{padding:0;margin:0}.chatgkd[data-v-d52f4355]{display:flex;flex-direction:column;height:100%;padding:50px 10px}.header[data-v-d52f4355]{position:fixed;left:0;right:0;top:0;height:50px;display:flex;align-items:center;padding:10px;background-color:#e2e2e2}.title[data-v-d52f4355]{font-size:24px;font-weight:600}.subtitle[data-v-d52f4355]{font-size:12px}.title-container[data-v-d52f4355]{flex:1;display:flex;align-items:center;flex-direction:column}.button[data-v-d52f4355]{color:#00f;border:1px solid #000;padding:5px;border-radius:5px}.footer[data-v-d52f4355]{position:fixed;left:0;right:0;height:50px}.help[data-v-d52f4355]{position:fixed;left:0;right:0;top:70px;background-color:#5361f6f2;color:#fff;padding:10px;margin:10px;border-radius:10px}.list[data-v-d52f4355]{flex:1;overflow-y:auto;margin-top:30px;margin-bottom:10px;padding:10px 10px 0;border-radius:10px;background-color:#efefef}.tips[data-v-d52f4355],.item[data-v-d52f4355]{padding-bottom:10px}.human-text[data-v-d52f4355]{font-weight:600}input[data-v-d52f4355]{width:100%;height:100%;border:none;outline:none;font-size:14px;padding:0 10px;background-color:#e2e2e2}.footer-button[data-v-d52f4355]{position:fixed;right:0;bottom:0;width:50px;height:50px}body{padding:0;margin:0} 2 | -------------------------------------------------------------------------------- /web/env.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | -------------------------------------------------------------------------------- /web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 19 | 20 | ChatGKD 21 | 22 | 23 |
24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /web/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chatgkd-web", 3 | "version": "0.0.0", 4 | "private": true, 5 | "scripts": { 6 | "dev": "vite", 7 | "build": "run-p type-check build-only", 8 | "preview": "vite preview", 9 | "build-only": "vite build", 10 | "type-check": "vue-tsc --noEmit", 11 | "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore" 12 | }, 13 | "dependencies": { 14 | "axios": "^1.3.4", 15 | "vue": "^3.2.45" 16 | }, 17 | "devDependencies": { 18 | "@rushstack/eslint-patch": "^1.1.4", 19 | "@types/node": "^18.11.12", 20 | "@vitejs/plugin-vue": "^4.0.0", 21 | "@vue/eslint-config-prettier": "^7.0.0", 22 | "@vue/eslint-config-typescript": "^11.0.0", 23 | "@vue/tsconfig": "^0.1.3", 24 | "eslint": "^8.22.0", 25 | "eslint-plugin-vue": "^9.3.0", 26 | "npm-run-all": "^4.1.5", 27 | "prettier": "^2.7.1", 28 | "typescript": "~4.7.4", 29 | "vite": "^4.0.0", 30 | "vite-plugin-pwa": "^0.14.4", 31 | "vue-tsc": "^1.0.12" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /web/src/App.vue: -------------------------------------------------------------------------------- 1 | 203 | 204 | 270 | 271 | 401 | -------------------------------------------------------------------------------- /web/src/AppState.ts: -------------------------------------------------------------------------------- 1 | import { reactive, watch } from "vue"; 2 | 3 | interface AppState { 4 | apiKey: string | null; 5 | history: string | null; 6 | prompt: string | null; 7 | } 8 | 9 | const appState: AppState = reactive({ 10 | apiKey: null, 11 | history: null, 12 | prompt: null, 13 | }); 14 | 15 | // 重复代码,待优化 TODO 16 | 17 | export function basePrompt() { 18 | const promptKey = "me.kingcos.chatgkd.prompt"; 19 | 20 | appState.prompt = localStorage.getItem(promptKey); 21 | 22 | watch( 23 | () => appState.prompt, 24 | (prompt) => { 25 | appState.prompt = prompt; 26 | if (prompt) { 27 | localStorage.setItem(promptKey, prompt); 28 | } else { 29 | localStorage.removeItem(promptKey); 30 | } 31 | } 32 | ); 33 | 34 | const setPrompt = (prompt: string) => { 35 | appState.prompt = prompt; 36 | }; 37 | 38 | const getPrompt = () => { 39 | return appState.prompt; 40 | }; 41 | 42 | return { getPrompt, setPrompt }; 43 | } 44 | 45 | export function chatHistory() { 46 | const storageKey = "me.kingcos.chatgkd.history"; 47 | 48 | appState.history = localStorage.getItem(storageKey); 49 | 50 | watch( 51 | () => appState.history, 52 | (history) => { 53 | appState.history = history; 54 | if (history) { 55 | localStorage.setItem(storageKey, history); 56 | } else { 57 | localStorage.removeItem(storageKey); 58 | } 59 | } 60 | ); 61 | 62 | const setHistory = (history: string) => { 63 | appState.history = history; 64 | }; 65 | 66 | const getHistory = () => { 67 | return appState.history; 68 | }; 69 | 70 | return { getHistory, setHistory }; 71 | } 72 | 73 | export function useApiKey() { 74 | const storageKey = "me.kingcos.chatgkd.apikey"; 75 | 76 | // 尝试从 localStorage 中获取 apiKey 77 | appState.apiKey = localStorage.getItem(storageKey); 78 | 79 | // 监听 apiKey 变化,存储在 localStorage 中 80 | watch( 81 | () => appState.apiKey, 82 | (apiKey) => { 83 | appState.apiKey = apiKey; 84 | if (apiKey) { 85 | localStorage.setItem(storageKey, apiKey); 86 | } else { 87 | localStorage.removeItem(storageKey); 88 | } 89 | } 90 | ); 91 | 92 | // 返回一个设置 apiKey 的方法 93 | const setApiKey = (apiKey: string) => { 94 | appState.apiKey = apiKey; 95 | }; 96 | 97 | const getApiKey = () => { 98 | return appState.apiKey; 99 | }; 100 | 101 | return { getApiKey, setApiKey }; 102 | } 103 | -------------------------------------------------------------------------------- /web/src/ChatGPTAPI.ts: -------------------------------------------------------------------------------- 1 | class ChatGPTAPI { 2 | private apiKey: string; 3 | private historyList: string[] = []; 4 | private controller: AbortController; 5 | private get urlRequest() { 6 | const url = "https://api.openai.com/v1/completions"; 7 | return new Request(url); 8 | } 9 | private dateFormatter = new Intl.DateTimeFormat("en-US", { 10 | year: "numeric", 11 | month: "2-digit", 12 | day: "2-digit", 13 | }); 14 | private basePrompt = `You are ChatGPT, a large language model trained by OpenAI. Respond conversationally. Do not answer as the user. Current date: ${this.dateFormatter.format( 15 | new Date() 16 | )} 17 | 18 | User: Hello 19 | ChatGPT: Hello! How can I help you today? \n\n\n`; 20 | 21 | constructor( 22 | apiKey: string, 23 | basePrompt: string | null = "", 24 | historyList: { userText: string; responseText: string }[] = [] 25 | ) { 26 | this.apiKey = apiKey; 27 | if (basePrompt) { 28 | this.basePrompt = basePrompt; 29 | } 30 | for (const { userText, responseText } of historyList) { 31 | this.appendToHistoryList(userText, responseText); 32 | } 33 | this.controller = new AbortController(); 34 | } 35 | 36 | private generateChatGPTPrompt(text: string): string { 37 | let prompt = `${this.basePrompt}${this.historyList.join( 38 | "" 39 | )}User: ${text}\nChatGPT:`; 40 | if (prompt.length > 4000 * 4) { 41 | this.historyList.shift(); 42 | prompt = this.generateChatGPTPrompt(text); 43 | } 44 | return prompt; 45 | } 46 | 47 | private async jsonBody( 48 | text: string, 49 | stream = true, 50 | signal?: AbortSignal 51 | ): Promise { 52 | const body = { 53 | model: "text-davinci-003", 54 | temperature: 0.5, 55 | max_tokens: 1024, 56 | prompt: this.generateChatGPTPrompt(text), 57 | stop: ["\n\n\n", "<|im_end|>"], 58 | stream: stream, 59 | }; 60 | const response = await fetch(this.urlRequest, { 61 | method: "POST", 62 | headers: { 63 | "Content-Type": "application/json", 64 | Authorization: `Bearer ${this.apiKey}`, 65 | }, 66 | body: JSON.stringify(body), 67 | signal: signal, 68 | }); 69 | 70 | if (response.ok) { 71 | const text = await response.text(); 72 | const result = text.trim().split("\n"); 73 | let responseText = ""; 74 | for (let i = 0; i < result.length; i++) { 75 | const line = result[i]; 76 | if (line.length == 0 || line == " ") { 77 | continue; 78 | } 79 | if (line.startsWith("data: ") && !line.endsWith("data: [DONE]")) { 80 | const text = JSON.parse(line.slice(6)).choices[0].text; 81 | responseText += text; 82 | console.log(`ChatGPT: ${text}`); 83 | } 84 | } 85 | 86 | return responseText; 87 | } else { 88 | throw new Error(`HTTP 异常!${response.status}`); 89 | } 90 | } 91 | 92 | private appendToHistoryList(userText: string, responseText: string) { 93 | this.historyList.push(`User: ${userText}\n\n\nChatGPT: ${responseText}\n`); 94 | } 95 | 96 | async sendMessageStream(text: string): Promise { 97 | const responseText = await this.jsonBody( 98 | text, 99 | true, 100 | this.controller.signal 101 | ); 102 | this.appendToHistoryList(text, responseText); 103 | return responseText; 104 | } 105 | 106 | stop() { 107 | this.controller.abort(); 108 | this.controller = new AbortController(); 109 | } 110 | 111 | // async sendMessage(text: string): Promise { 112 | // const responseText = await this.jsonBody(text, false); 113 | // this.appendToHistoryList(text, responseText); 114 | // return responseText; 115 | // } 116 | } 117 | 118 | export default ChatGPTAPI; 119 | -------------------------------------------------------------------------------- /web/src/OpenAIChatAPI.ts: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | import type { AxiosRequestConfig, CancelTokenSource } from "axios"; 3 | 4 | export enum Role { 5 | user = "user", 6 | system = "system", 7 | assistant = "assistant", 8 | } 9 | 10 | interface ChatCompletion { 11 | id: string; 12 | object: string; 13 | created: number; 14 | model: string; 15 | usage: { 16 | prompt_tokens: number; 17 | completion_tokens: number; 18 | total_tokens: number; 19 | }; 20 | choices: [ 21 | { 22 | message: { 23 | role: string; 24 | content: string; 25 | }; 26 | finish_reason: string; 27 | index: number; 28 | } 29 | ]; 30 | } 31 | 32 | class OpenAIChatAPI { 33 | private readonly apiKey: string; 34 | private readonly model: string = "gpt-3.5-turbo"; 35 | 36 | private chatHistory: { role: Role; content: string }[] = []; 37 | private source: CancelTokenSource = axios.CancelToken.source(); 38 | 39 | constructor( 40 | apiKey: string, 41 | prompt: string | null = null, 42 | chatHistory: { role: Role; content: string }[] = [] 43 | ) { 44 | this.apiKey = apiKey; 45 | if (prompt) { 46 | this.appendHistory(prompt, Role.system); 47 | } 48 | this.chatHistory = this.chatHistory.concat(chatHistory); 49 | // if (model) { 50 | // this.model = model; 51 | // } 52 | } 53 | 54 | // Public 55 | async send(message: string, timeout: number = 5000): Promise { 56 | // 发送消息 57 | this.appendHistory(message); 58 | const response = await axios(this.requestConfig()); 59 | console.log(response.data); 60 | 61 | const responsData: ChatCompletion = response.data; 62 | 63 | if (responsData.choices.length) { 64 | message = responsData.choices[0].message.content; 65 | this.appendHistory(message, Role.assistant); 66 | return message; 67 | } else { 68 | throw new Error(`接口响应异常!${response.data}`); 69 | } 70 | } 71 | 72 | cancel() { 73 | // 终止本次对话 74 | this.source.cancel("已手动终止本次请求"); 75 | } 76 | 77 | // Private 78 | private appendHistory(content: string, role: Role = Role.user) { 79 | this.chatHistory.push({ 80 | role: role, 81 | content: content, 82 | }); 83 | } 84 | 85 | private requestConfig(): AxiosRequestConfig { 86 | return { 87 | method: "post", 88 | url: "https://api.openai.com/v1/chat/completions", 89 | headers: { 90 | "Content-Type": "application/json", 91 | Authorization: `Bearer ${this.apiKey}`, 92 | }, 93 | data: { model: this.model, messages: this.chatHistory }, 94 | cancelToken: this.source?.token, 95 | }; 96 | } 97 | } 98 | 99 | export default OpenAIChatAPI; 100 | -------------------------------------------------------------------------------- /web/src/assets/main.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 0px; 3 | margin: 0px; 4 | } 5 | -------------------------------------------------------------------------------- /web/src/main.ts: -------------------------------------------------------------------------------- 1 | import { createApp } from "vue"; 2 | import App from "./App.vue"; 3 | 4 | import "./assets/main.css"; 5 | 6 | createApp(App).mount("#app"); 7 | -------------------------------------------------------------------------------- /web/tsconfig.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.node.json", 3 | "include": ["vite.config.*", "vitest.config.*", "cypress.config.*", "playwright.config.*"], 4 | "compilerOptions": { 5 | "composite": true, 6 | "types": ["node"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /web/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "@vue/tsconfig/tsconfig.web.json", 3 | "include": ["env.d.ts", "src/**/*", "src/**/*.vue"], 4 | "compilerOptions": { 5 | "baseUrl": "/ChatGKD/", 6 | "paths": { 7 | "@/*": ["./src/*"] 8 | } 9 | }, 10 | 11 | "references": [ 12 | { 13 | "path": "./tsconfig.config.json" 14 | } 15 | ] 16 | } 17 | -------------------------------------------------------------------------------- /web/vite.config.ts: -------------------------------------------------------------------------------- 1 | import { VitePWA } from "vite-plugin-pwa"; 2 | import { fileURLToPath, URL } from "node:url"; 3 | 4 | import { defineConfig } from "vite"; 5 | import vue from "@vitejs/plugin-vue"; 6 | 7 | // https://vitejs.dev/config/ 8 | export default defineConfig({ 9 | base: process.env.NODE_ENV === "development" ? "" : "/ChatGKD/", 10 | plugins: [vue(), VitePWA()], 11 | resolve: { 12 | alias: { 13 | "@": fileURLToPath(new URL("./src", import.meta.url)), 14 | }, 15 | }, 16 | }); 17 | -------------------------------------------------------------------------------- /workbox-7369c0e1.js: -------------------------------------------------------------------------------- 1 | define(["exports"],(function(t){"use strict";try{self["workbox:core:6.5.3"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:6.5.3"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super((({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)}),e,s)}}class o{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",(t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)}))}addCacheListener(){self.addEventListener("message",(t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map((e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})})));t.waitUntil(s),t.ports&&t.ports[0]&&s.then((()=>t.ports[0].postMessage(!0)))}}))}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let o=r&&r.handler;const c=t.method;if(!o&&this.i.has(c)&&(o=this.i.get(c)),!o)return;let a;try{a=o.handle({url:s,request:t,event:e,params:i})}catch(t){a=Promise.reject(t)}const h=r&&r.catchHandler;return a instanceof Promise&&(this.o||h)&&(a=a.catch((async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n}))),a}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const o=r.match({url:t,sameOrigin:e,request:s,event:n});if(o)return i=o,(Array.isArray(i)&&0===i.length||o.constructor===Object&&0===Object.keys(o).length||"boolean"==typeof o)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let c;const a=()=>(c||(c=new o,c.addFetchListener(),c.addCacheListener()),c);function h(t,e,n){let o;if("string"==typeof t){const s=new URL(t,location.href);o=new i((({url:t})=>t.href===s.href),e,n)}else if(t instanceof RegExp)o=new r(t,e,n);else if("function"==typeof t)o=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});o=t}return a().registerRoute(o),o}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter((t=>t&&t.length>0)).join("-"),f={updateDetails:t=>{(t=>{for(const e of Object.keys(u))t(e)})((e=>{"string"==typeof t[e]&&(u[e]=t[e])}))},getGoogleAnalyticsName:t=>t||l(u.googleAnalytics),getPrecacheName:t=>t||l(u.precache),getPrefix:()=>u.prefix,getRuntimeName:t=>t||l(u.runtime),getSuffix:()=>u.suffix};function w(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:6.5.3"]&&_()}catch(t){}const d="__WB_REVISION__";function p(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set(d,e),{cacheKey:i.href,url:r.href}}class y{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class g{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.h.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.h=t}}let R;async function m(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=e?e(r):r,c=function(){if(void 0===R){const t=new Response("");if("body"in t)try{new Response(t.body),R=!0}catch(t){R=!1}R=!1}return R}()?i.body:await i.blob();return new Response(c,o)}function v(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class q{constructor(){this.promise=new Promise(((t,e)=>{this.resolve=t,this.reject=e}))}}const U=new Set;try{self["workbox:strategies:6.5.3"]&&_()}catch(t){}function b(t){return"string"==typeof t?new Request(t):t}class L{constructor(t,e){this.u={},Object.assign(this,e),this.event=e.event,this.l=t,this.p=new q,this.g=[],this.R=[...t.plugins],this.m=new Map;for(const t of this.R)this.m.set(t,{});this.event.waitUntil(this.p.promise)}async fetch(t){const{event:e}=this;let n=b(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.l.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=b(t);let s;const{cacheName:n,matchOptions:i}=this.l,r=await this.getCacheKey(e,"read"),o=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,o);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=b(t);var i;await(i=0,new Promise((t=>setTimeout(t,i))));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(o=r.url,new URL(String(o),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var o;const c=await this.v(e);if(!c)return!1;const{cacheName:a,matchOptions:h}=this.l,u=await self.caches.open(a),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=v(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),o=await t.keys(e,r);for(const e of o)if(i===v(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?c.clone():c)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of U)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:a,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.u[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=b(await t({mode:e,request:n,event:this.event,params:this.params}));this.u[s]=n}return this.u[s]}hasCallback(t){for(const e of this.l.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.l.plugins)if("function"==typeof e[t]){const s=this.m.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.g.push(t),t}async doneWaiting(){let t;for(;t=this.g.shift();)await t}destroy(){this.p.resolve(null)}async v(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class x{constructor(t={}){this.cacheName=f.getRuntimeName(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new L(this,{event:e,request:s,params:n}),r=this.q(i,s,e);return[r,this.U(r,i,s,e)]}async q(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this.L(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async U(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}class C extends x{constructor(t={}){t.cacheName=f.getPrecacheName(t.cacheName),super(t),this._=!1!==t.fallbackToNetwork,this.plugins.push(C.copyRedirectedCacheableResponsesPlugin)}async L(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.C(t,e):await this.N(t,e))}async N(t,e){let n;const i=e.params||{};if(!this._)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,o=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&o&&"no-cors"!==t.mode&&(this.O(),await e.cachePut(t,n.clone()))}return n}async C(t,e){this.O();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}O(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==C.copyRedirectedCacheableResponsesPlugin&&(n===C.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(C.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}C.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},C.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await m(t):t};class E{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.P=new Map,this.j=new Map,this.k=new Map,this.l=new C({cacheName:f.getPrecacheName(t),plugins:[...e,new g({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.l}precache(t){this.addToCacheList(t),this.K||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.K=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=p(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.P.has(i)&&this.P.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.P.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.k.has(t)&&this.k.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.k.set(t,n.integrity)}if(this.P.set(i,t),this.j.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return w(t,(async()=>{const e=new y;this.strategy.plugins.push(e);for(const[e,s]of this.P){const n=this.k.get(s),i=this.j.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}}))}activate(t){return w(t,(async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.P.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}}))}getURLsToCacheKeys(){return this.P}getCachedURLs(){return[...this.P.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.P.get(e.href)}getIntegrityForCacheKey(t){return this.k.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}let N;const O=()=>(N||(N=new E),N);class P extends i{constructor(t,e){super((({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const o=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some((t=>t.test(s)))&&t.searchParams.delete(s);return t}(r,e);if(yield o.href,s&&o.pathname.endsWith("/")){const t=new URL(o.href);t.pathname+=s,yield t.href}if(n){const t=new URL(o.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}}),t.strategy)}}const j=async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter((s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t));return await Promise.all(s.map((t=>self.caches.delete(t)))),s};t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super((t=>this.S(t)),t),this.T=e,this.W=s}S({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.W)if(t.test(s))return!1;return!!this.T.some((t=>t.test(s)))}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",(t=>{const e=f.getPrecacheName();t.waitUntil(j(e).then((t=>{})))}))},t.createHandlerBoundToURL=function(t){return O().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){O().precache(t)}(t),function(t){const e=O();h(new P(e,t))}(e)},t.registerRoute=h})); 2 | --------------------------------------------------------------------------------