diff --git a/.eslintignore b/.eslintignore index 06d9bf00..e3053150 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,2 +1,3 @@ # aliyun edgescript -*.edgescript \ No newline at end of file +*.edgescript +src/vendors \ No newline at end of file diff --git a/.eslintrc b/.eslintrc index 9a24677c..295a72d2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -19,7 +19,13 @@ "vuetify/no-legacy-grid": "error", "vue/no-v-html": "off", "vue/no-template-shadow": "off", - "vue/valid-template-root": "off" + "vue/valid-template-root": "off", + "no-tabs": [ + "error", + { + "allowIndentationTabs": true + } + ] }, "parserOptions": { "parser": "babel-eslint" diff --git a/.gitignore b/.gitignore index 96172bbf..bf8e5c4d 100644 --- a/.gitignore +++ b/.gitignore @@ -20,3 +20,7 @@ package-lock.json *.njsproj *.sln *.sw? +tools/skeleton-html-generator/dist +tools/skeleton-html-generator/.cache +src/utils/vendors/ +src/vendors/ diff --git a/LICENSE b/LICENSE index 6cf525b2..852c6561 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2020 Penguin Statistics +Copyright (c) 2021 Penguin Statistics Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/android/app/build.gradle b/android/app/build.gradle index eb4e1719..0974e0b3 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -1,13 +1,15 @@ apply plugin: 'com.android.application' +apply plugin: 'com.google.gms.google-services' + android { compileSdkVersion rootProject.ext.compileSdkVersion defaultConfig { applicationId "io.penguinstats.app" minSdkVersion rootProject.ext.minSdkVersion targetSdkVersion rootProject.ext.targetSdkVersion - versionCode 1 - versionName "1.0" + versionCode 2 + versionName "3.4.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { @@ -32,6 +34,7 @@ dependencies { androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion" androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion" implementation project(':capacitor-cordova-android-plugins') + implementation platform('com.google.firebase:firebase-bom:26.3.0') } apply from: 'capacitor.build.gradle' diff --git a/android/app/google-services.json b/android/app/google-services.json new file mode 100644 index 00000000..d2735ded --- /dev/null +++ b/android/app/google-services.json @@ -0,0 +1,39 @@ +{ + "project_info": { + "project_number": "200614453783", + "project_id": "penguin-statistics", + "storage_bucket": "penguin-statistics.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:200614453783:android:be9e2507cdfa945d147252", + "android_client_info": { + "package_name": "io.penguinstats.app" + } + }, + "oauth_client": [ + { + "client_id": "200614453783-q3q89lurq4nmm1mn9pnkf3qa1e0k16mi.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCA225z1ov8mJ-oRXOr96fh6jPg_aeI5T4" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "200614453783-q3q89lurq4nmm1mn9pnkf3qa1e0k16mi.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index c65b8fe2..f3eb56ff 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -22,13 +22,44 @@ - + + + + - - - + + + + + + + + + + + + + + + + + + + + @@ -40,7 +71,7 @@ android:grantUriPermissions="true"> + android:resource="@xml/file_paths" /> @@ -48,18 +79,18 @@ - - + + - - - + + + - + - - + + diff --git a/android/app/src/main/assets/capacitor.config.json b/android/app/src/main/assets/capacitor.config.json index 4b755e8f..a40dd97c 100644 --- a/android/app/src/main/assets/capacitor.config.json +++ b/android/app/src/main/assets/capacitor.config.json @@ -1,7 +1,7 @@ { "appId": "io.penguinstats.app", "appName": "企鹅物流", - "bundledWebRuntime": false, + "bundledWebRuntime": true, "npmClient": "yarn", "webDir": "dist", "plugins": { @@ -9,7 +9,8 @@ "launchAutoHide": false, "backgroundColor": "#000000ff", "showSpinner": true, - "spinnerColor": "#fff" + "spinnerColor": "#fff", + "splashFullScreen": true }, "PushNotifications": { "presentationOptions": ["badge", "sound", "alert"] diff --git a/android/app/src/main/java/io/penguinstats/app/MainActivity.java b/android/app/src/main/java/io/penguinstats/app/MainActivity.java index 84d838df..2f0e5db1 100644 --- a/android/app/src/main/java/io/penguinstats/app/MainActivity.java +++ b/android/app/src/main/java/io/penguinstats/app/MainActivity.java @@ -17,5 +17,7 @@ public void onCreate(Bundle savedInstanceState) { // Additional plugins you've installed go here // Ex: add(TotallyAwesomePlugin.class); }}); + + this.getBridge().logToJs("MainActivity--onCreate: launching app with savedInstanceState " + savedInstanceState); } } diff --git a/android/app/src/main/java/io/penguinstats/app/SearchMetaActivity.java b/android/app/src/main/java/io/penguinstats/app/SearchMetaActivity.java new file mode 100644 index 00000000..ba50c581 --- /dev/null +++ b/android/app/src/main/java/io/penguinstats/app/SearchMetaActivity.java @@ -0,0 +1,29 @@ +package io.penguinstats.app; + +import android.net.Uri; +import android.os.Bundle; + +import com.getcapacitor.Plugin; + +import java.util.ArrayList; + +public class SearchMetaActivity extends MainActivity { + @Override + public void onCreate(Bundle savedInstanceState) { + if (this.getBridge() == null) { + super.onCreate(savedInstanceState); + + // Initializes the Bridge + this.init(savedInstanceState, new ArrayList>() {{ + // Additional plugins you've installed go here + // Ex: add(TotallyAwesomePlugin.class); + }}); + } + + Uri uri = Uri.parse("https://penguin-stats.io/search"); + + this.getBridge().logToJs("onCreate: uri parsed as " + uri); + + this.getBridge().launchIntent(uri); + } +} diff --git a/android/app/src/main/res/drawable-anydpi/search.xml b/android/app/src/main/res/drawable-anydpi/search.xml new file mode 100644 index 00000000..093a5b7a --- /dev/null +++ b/android/app/src/main/res/drawable-anydpi/search.xml @@ -0,0 +1,16 @@ + + + + + diff --git a/android/app/src/main/res/drawable-hdpi/search.png b/android/app/src/main/res/drawable-hdpi/search.png new file mode 100644 index 00000000..ef614f37 Binary files /dev/null and b/android/app/src/main/res/drawable-hdpi/search.png differ diff --git a/android/app/src/main/res/drawable-land-hdpi/splash.png b/android/app/src/main/res/drawable-land-hdpi/splash.png index d395e71d..edca8d2d 100644 Binary files a/android/app/src/main/res/drawable-land-hdpi/splash.png and b/android/app/src/main/res/drawable-land-hdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-mdpi/splash.png b/android/app/src/main/res/drawable-land-mdpi/splash.png index cb8cc4bf..ade38f86 100644 Binary files a/android/app/src/main/res/drawable-land-mdpi/splash.png and b/android/app/src/main/res/drawable-land-mdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xhdpi/splash.png b/android/app/src/main/res/drawable-land-xhdpi/splash.png index f18b610d..a582e1c3 100644 Binary files a/android/app/src/main/res/drawable-land-xhdpi/splash.png and b/android/app/src/main/res/drawable-land-xhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxhdpi/splash.png index d24d77ee..caae83f5 100644 Binary files a/android/app/src/main/res/drawable-land-xxhdpi/splash.png and b/android/app/src/main/res/drawable-land-xxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png index 0c524929..a7edef4e 100644 Binary files a/android/app/src/main/res/drawable-land-xxxhdpi/splash.png and b/android/app/src/main/res/drawable-land-xxxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-mdpi/search.png b/android/app/src/main/res/drawable-mdpi/search.png new file mode 100644 index 00000000..8c72672c Binary files /dev/null and b/android/app/src/main/res/drawable-mdpi/search.png differ diff --git a/android/app/src/main/res/drawable-port-hdpi/splash.png b/android/app/src/main/res/drawable-port-hdpi/splash.png index 963d9b6e..49f08064 100644 Binary files a/android/app/src/main/res/drawable-port-hdpi/splash.png and b/android/app/src/main/res/drawable-port-hdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-mdpi/splash.png b/android/app/src/main/res/drawable-port-mdpi/splash.png index be2a7cca..bebfc494 100644 Binary files a/android/app/src/main/res/drawable-port-mdpi/splash.png and b/android/app/src/main/res/drawable-port-mdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xhdpi/splash.png b/android/app/src/main/res/drawable-port-xhdpi/splash.png index 61485ab9..fb8bd434 100644 Binary files a/android/app/src/main/res/drawable-port-xhdpi/splash.png and b/android/app/src/main/res/drawable-port-xhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxhdpi/splash.png index fbae5aba..332ff320 100644 Binary files a/android/app/src/main/res/drawable-port-xxhdpi/splash.png and b/android/app/src/main/res/drawable-port-xxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png index 034151ef..584010af 100644 Binary files a/android/app/src/main/res/drawable-port-xxxhdpi/splash.png and b/android/app/src/main/res/drawable-port-xxxhdpi/splash.png differ diff --git a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml deleted file mode 100644 index c7bd21db..00000000 --- a/android/app/src/main/res/drawable-v24/ic_launcher_foreground.xml +++ /dev/null @@ -1,34 +0,0 @@ - - - - - - - - - - - diff --git a/android/app/src/main/res/drawable-xhdpi/search.png b/android/app/src/main/res/drawable-xhdpi/search.png new file mode 100644 index 00000000..7d64b190 Binary files /dev/null and b/android/app/src/main/res/drawable-xhdpi/search.png differ diff --git a/android/app/src/main/res/drawable-xxhdpi/search.png b/android/app/src/main/res/drawable-xxhdpi/search.png new file mode 100644 index 00000000..e1d08221 Binary files /dev/null and b/android/app/src/main/res/drawable-xxhdpi/search.png differ diff --git a/android/app/src/main/res/drawable/ic_launcher_background.xml b/android/app/src/main/res/drawable/ic_launcher_background.xml index d5fccc53..da7b51ca 100644 --- a/android/app/src/main/res/drawable/ic_launcher_background.xml +++ b/android/app/src/main/res/drawable/ic_launcher_background.xml @@ -1,170 +1,14 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + diff --git a/android/app/src/main/res/drawable/splash.png b/android/app/src/main/res/drawable/splash.png index cb8cc4bf..ade38f86 100644 Binary files a/android/app/src/main/res/drawable/splash.png and b/android/app/src/main/res/drawable/splash.png differ diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml index 036d09bc..c4a603d4 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml index 036d09bc..c4a603d4 100644 --- a/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml +++ b/android/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -1,5 +1,5 @@ - + \ No newline at end of file diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png index 116814ae..1fee6a9e 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png index 2127973b..caf72047 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png index 116814ae..1fee6a9e 100644 Binary files a/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png index b4c66b53..e77f08de 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png index 8ed0605c..63c01ca6 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png index b4c66b53..e77f08de 100644 Binary files a/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png index 5cf34eef..291267d4 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png index df0f1588..22cc07e9 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png index 5cf34eef..291267d4 100644 Binary files a/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png index 2e771977..62015e2a 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png index 2960cbb6..94e893b8 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png index 2e771977..62015e2a 100644 Binary files a/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png index 02746b41..8af0b65d 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png index d2ea9abe..bba94de4 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_foreground.png differ diff --git a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png index 02746b41..8af0b65d 100644 Binary files a/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png and b/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/android/app/src/main/res/values-ja/strings.xml b/android/app/src/main/res/values-ja/strings.xml new file mode 100644 index 00000000..9f740907 --- /dev/null +++ b/android/app/src/main/res/values-ja/strings.xml @@ -0,0 +1,6 @@ + + + ペン急統計 + ペン急統計 + 検索 + \ No newline at end of file diff --git a/android/app/src/main/res/values-zh/strings.xml b/android/app/src/main/res/values-zh/strings.xml new file mode 100644 index 00000000..fda7b9c5 --- /dev/null +++ b/android/app/src/main/res/values-zh/strings.xml @@ -0,0 +1,6 @@ + + + 企鹅物流 + 企鹅物流 + 搜索 + \ No newline at end of file diff --git a/android/app/src/main/res/values/ic_launcher_background.xml b/android/app/src/main/res/values/ic_launcher_background.xml deleted file mode 100644 index c5d5899f..00000000 --- a/android/app/src/main/res/values/ic_launcher_background.xml +++ /dev/null @@ -1,4 +0,0 @@ - - - #FFFFFF - \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 30fcea99..3cd690a7 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,7 +1,9 @@ - penguin-stats-frontend - penguin-stats-frontend - io.penguinstats.app - io.penguinstats.app + Penguin Stats + Penguin Stats + io.penguinstats.app + io.penguinstats.app + + 搜索 diff --git a/android/app/src/main/res/values/styles.xml b/android/app/src/main/res/values/styles.xml index bb45498f..6a3d6d53 100644 --- a/android/app/src/main/res/values/styles.xml +++ b/android/app/src/main/res/values/styles.xml @@ -7,16 +7,21 @@ @color/colorPrimary @color/colorPrimaryDark @color/colorAccent + + @color/colorPrimaryDark \ No newline at end of file diff --git a/android/app/src/main/res/xml/shortcuts.xml b/android/app/src/main/res/xml/shortcuts.xml new file mode 100644 index 00000000..6008f39a --- /dev/null +++ b/android/app/src/main/res/xml/shortcuts.xml @@ -0,0 +1,14 @@ + + + + + + \ No newline at end of file diff --git a/android/gradlew b/android/gradlew old mode 100755 new mode 100644 diff --git a/android/gradlew.bat b/android/gradlew.bat index 24467a14..9618d8d9 100644 --- a/android/gradlew.bat +++ b/android/gradlew.bat @@ -1,100 +1,100 @@ -@rem -@rem Copyright 2015 the original author or authors. -@rem -@rem Licensed under the Apache License, Version 2.0 (the "License"); -@rem you may not use this file except in compliance with the License. -@rem You may obtain a copy of the License at -@rem -@rem https://www.apache.org/licenses/LICENSE-2.0 -@rem -@rem Unless required by applicable law or agreed to in writing, software -@rem distributed under the License is distributed on an "AS IS" BASIS, -@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -@rem See the License for the specific language governing permissions and -@rem limitations under the License. -@rem - -@if "%DEBUG%" == "" @echo off -@rem ########################################################################## -@rem -@rem Gradle startup script for Windows -@rem -@rem ########################################################################## - -@rem Set local scope for the variables with windows NT shell -if "%OS%"=="Windows_NT" setlocal - -set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. -set APP_BASE_NAME=%~n0 -set APP_HOME=%DIRNAME% - -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" - -@rem Find java.exe -if defined JAVA_HOME goto findJavaFromJavaHome - -set JAVA_EXE=java.exe -%JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init - -echo. -echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:findJavaFromJavaHome -set JAVA_HOME=%JAVA_HOME:"=% -set JAVA_EXE=%JAVA_HOME%/bin/java.exe - -if exist "%JAVA_EXE%" goto init - -echo. -echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% -echo. -echo Please set the JAVA_HOME variable in your environment to match the -echo location of your Java installation. - -goto fail - -:init -@rem Get command-line arguments, handling Windows variants - -if not "%OS%" == "Windows_NT" goto win9xME_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* - -:execute -@rem Setup the command line - -set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar - -@rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% - -:end -@rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd - -:fail -rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of -rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 - -:mainEnd -if "%OS%"=="Windows_NT" endlocal - -:omega +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windows variants + +if not "%OS%" == "Windows_NT" goto win9xME_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/babel.config.js b/babel.config.js index cca4a1a9..639f4db1 100644 --- a/babel.config.js +++ b/babel.config.js @@ -1,10 +1,10 @@ module.exports = { presets: [ - ["@vue/cli-plugin-babel/preset", { - useBuiltIns: "entry" + ['@vue/cli-plugin-babel/preset', { + useBuiltIns: 'entry' }] ], plugins: [ - "@babel/plugin-transform-modules-commonjs" + '@babel/plugin-transform-modules-commonjs' ] } diff --git a/capacitor.config.json b/capacitor.config.json index 4b755e8f..a40dd97c 100644 --- a/capacitor.config.json +++ b/capacitor.config.json @@ -1,7 +1,7 @@ { "appId": "io.penguinstats.app", "appName": "企鹅物流", - "bundledWebRuntime": false, + "bundledWebRuntime": true, "npmClient": "yarn", "webDir": "dist", "plugins": { @@ -9,7 +9,8 @@ "launchAutoHide": false, "backgroundColor": "#000000ff", "showSpinner": true, - "spinnerColor": "#fff" + "spinnerColor": "#fff", + "splashFullScreen": true }, "PushNotifications": { "presentationOptions": ["badge", "sound", "alert"] diff --git a/ios/App/App.xcodeproj/project.pbxproj b/ios/App/App.xcodeproj/project.pbxproj index efe86794..61c319a2 100644 --- a/ios/App/App.xcodeproj/project.pbxproj +++ b/ios/App/App.xcodeproj/project.pbxproj @@ -14,29 +14,33 @@ 3A001AD72599A68A0078A265 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A001AD62599A68A0078A265 /* Helpers.swift */; }; 3A06C1102597112E00B81F31 /* SiteStats.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C10F2597112E00B81F31 /* SiteStats.swift */; }; 3A06C118259720D600B81F31 /* PenguinWidget.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C117259720D600B81F31 /* PenguinWidget.swift */; }; - 3A06C120259743B900B81F31 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C11F259743B900B81F31 /* Helpers.swift */; }; 3A06C1252597447200B81F31 /* StageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C1242597447200B81F31 /* StageView.swift */; }; 3A06C12D2597454600B81F31 /* WidgetFooter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C12C2597454600B81F31 /* WidgetFooter.swift */; }; 3A06C133259766C400B81F31 /* WidgetEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C132259766C400B81F31 /* WidgetEntry.swift */; }; 3A06C13B25976DAF00B81F31 /* MediumWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A06C13A25976DAF00B81F31 /* MediumWidgetView.swift */; }; + 3A0C886325C25E8E008E1F4B /* PushManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A0C886225C25E8E008E1F4B /* PushManager.swift */; }; 3A1157AD258F2B5C00F4C6FD /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A00D83125266410007308FB /* WidgetKit.framework */; }; 3A1157AE258F2B5C00F4C6FD /* SwiftUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3A00D83325266410007308FB /* SwiftUI.framework */; }; 3A1157B1258F2B5C00F4C6FD /* SmallWidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1157B0258F2B5C00F4C6FD /* SmallWidgetView.swift */; }; 3A1157B4258F2B5E00F4C6FD /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A1157B3258F2B5E00F4C6FD /* Assets.xcassets */; }; 3A1157BA258F2B5E00F4C6FD /* PenguinWidgetExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3A1157AC258F2B5C00F4C6FD /* PenguinWidgetExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 3A20895A25C26EFB001D7490 /* Alamofire in Frameworks */ = {isa = PBXBuildFile; productRef = 3A20895925C26EFB001D7490 /* Alamofire */; }; + 3A20895D25C2ACC5001D7490 /* Helpers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A001AD62599A68A0078A265 /* Helpers.swift */; }; + 3A33A3D825D3DA96001867F0 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3A33A3DB25D3DA96001867F0 /* Intents.intentdefinition */; }; + 3A33A3D925D3DA96001867F0 /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3A33A3DB25D3DA96001867F0 /* Intents.intentdefinition */; }; + 3A3F035B25C0B3D000DEED16 /* PersistenceManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3F035A25C0B3D000DEED16 /* PersistenceManager.swift */; }; 3A4D4431259AC0BA000807F8 /* InitialLaunch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A4D4430259AC0BA000807F8 /* InitialLaunch.swift */; }; 3A5051A925965532004167D3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3A5051AC25965532004167D3 /* Localizable.strings */; }; 3A5051AA25965532004167D3 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3A5051AC25965532004167D3 /* Localizable.strings */; }; 3A5051B82596575D004167D3 /* Bender.ttf in Resources */ = {isa = PBXBuildFile; fileRef = 3A5051B72596575D004167D3 /* Bender.ttf */; }; 3A5051C1259666FB004167D3 /* ItemStatsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A5051C0259666FB004167D3 /* ItemStatsView.swift */; }; 3A5051C9259669AF004167D3 /* ItemIcons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3A5051C8259669AF004167D3 /* ItemIcons.xcassets */; }; - 3A55B60F2598D9F500699BBA /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3A55B6132598D9F500699BBA /* Intents.intentdefinition */; }; - 3A55B6102598D9F500699BBA /* Intents.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 3A55B6132598D9F500699BBA /* Intents.intentdefinition */; }; 3A55B6842599056000699BBA /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A55B6832599056000699BBA /* Constants.swift */; }; 3A61615A259B0ED200FA06A2 /* ToggleNotificationPreference.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A616159259B0ED200FA06A2 /* ToggleNotificationPreference.swift */; }; 3A616162259B2D2D00FA06A2 /* Debugger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A616161259B2D2D00FA06A2 /* Debugger.swift */; }; 3A616168259C698B00FA06A2 /* NotificationPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A616167259C698B00FA06A2 /* NotificationPreferences.swift */; }; 3A61616C259C7B8D00FA06A2 /* HapticButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A61616B259C7B8D00FA06A2 /* HapticButton.swift */; }; + 3A65B09725C662EE00E1AE2A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3A65B09525C662EE00E1AE2A /* LaunchScreen.storyboard */; }; 3A679B012599166C00A685E9 /* WelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A679B002599166C00A685E9 /* WelcomeView.swift */; }; 3A885ACA25A43F0400247AED /* RxBus in Frameworks */ = {isa = PBXBuildFile; productRef = 3A885AC925A43F0400247AED /* RxBus */; }; 3A885ACE25A443D600247AED /* EventBus.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A885ACD25A443D600247AED /* EventBus.swift */; }; @@ -90,15 +94,18 @@ 3A00D83325266410007308FB /* SwiftUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SwiftUI.framework; path = System/Library/Frameworks/SwiftUI.framework; sourceTree = SDKROOT; }; 3A06C10F2597112E00B81F31 /* SiteStats.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SiteStats.swift; sourceTree = ""; }; 3A06C117259720D600B81F31 /* PenguinWidget.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PenguinWidget.swift; sourceTree = ""; }; - 3A06C11F259743B900B81F31 /* Helpers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Helpers.swift; sourceTree = ""; }; 3A06C1242597447200B81F31 /* StageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StageView.swift; sourceTree = ""; }; 3A06C12C2597454600B81F31 /* WidgetFooter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetFooter.swift; sourceTree = ""; }; 3A06C132259766C400B81F31 /* WidgetEntry.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetEntry.swift; sourceTree = ""; }; 3A06C13A25976DAF00B81F31 /* MediumWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MediumWidgetView.swift; sourceTree = ""; }; + 3A0C886225C25E8E008E1F4B /* PushManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushManager.swift; sourceTree = ""; }; 3A1157AC258F2B5C00F4C6FD /* PenguinWidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = PenguinWidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 3A1157B0258F2B5C00F4C6FD /* SmallWidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmallWidgetView.swift; sourceTree = ""; }; 3A1157B3258F2B5E00F4C6FD /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 3A1157B5258F2B5E00F4C6FD /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 3A33A3DA25D3DA96001867F0 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = en; path = en.lproj/Intents.intentdefinition; sourceTree = ""; }; + 3A33A3DF25D3DAA2001867F0 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Intents.strings"; sourceTree = ""; }; + 3A3F035A25C0B3D000DEED16 /* PersistenceManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PersistenceManager.swift; sourceTree = ""; }; 3A4D4430259AC0BA000807F8 /* InitialLaunch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InitialLaunch.swift; sourceTree = ""; }; 3A5051AB25965532004167D3 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 3A5051B025965533004167D3 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; @@ -110,8 +117,8 @@ 3A616161259B2D2D00FA06A2 /* Debugger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Debugger.swift; sourceTree = ""; }; 3A616167259C698B00FA06A2 /* NotificationPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationPreferences.swift; sourceTree = ""; }; 3A61616B259C7B8D00FA06A2 /* HapticButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HapticButton.swift; sourceTree = ""; }; + 3A65B09625C662EE00E1AE2A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 3A679B002599166C00A685E9 /* WelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WelcomeView.swift; sourceTree = ""; }; - 3A885ABF25A0157A00247AED /* en */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; name = en; path = en.lproj/Intents.intentdefinition; sourceTree = ""; }; 3A885ACD25A443D600247AED /* EventBus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventBus.swift; sourceTree = ""; }; 3A885AD125A4477600247AED /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 3A8EFF982599BBC100B6A788 /* alert1.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = alert1.caf; sourceTree = ""; }; @@ -142,6 +149,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 3A20895A25C26EFB001D7490 /* Alamofire in Frameworks */, 3A1157AE258F2B5C00F4C6FD /* SwiftUI.framework in Frameworks */, 3A1157AD258F2B5C00F4C6FD /* WidgetKit.framework in Frameworks */, ); @@ -194,10 +202,9 @@ 3A5051C8259669AF004167D3 /* ItemIcons.xcassets */, 3A06C10F2597112E00B81F31 /* SiteStats.swift */, 3A06C117259720D600B81F31 /* PenguinWidget.swift */, - 3A06C11F259743B900B81F31 /* Helpers.swift */, 3A06C132259766C400B81F31 /* WidgetEntry.swift */, 3A968BB92597A738005266F2 /* ExternalService.swift */, - 3A55B6132598D9F500699BBA /* Intents.intentdefinition */, + 3A33A3DB25D3DA96001867F0 /* Intents.intentdefinition */, ); path = PenguinWidget; sourceTree = ""; @@ -231,6 +238,8 @@ isa = PBXGroup; children = ( 3A616167259C698B00FA06A2 /* NotificationPreferences.swift */, + 3A3F035A25C0B3D000DEED16 /* PersistenceManager.swift */, + 3A0C886225C25E8E008E1F4B /* PushManager.swift */, ); path = Repositories; sourceTree = ""; @@ -253,6 +262,7 @@ 3AA7E34B2522510700387971 /* App.entitlements */, 504EC3071FED79650016851F /* AppDelegate.swift */, 504EC30B1FED79650016851F /* Main.storyboard */, + 3A65B09525C662EE00E1AE2A /* LaunchScreen.storyboard */, 504EC3131FED79650016851F /* Info.plist */, 2FAD9762203C412B000D30F8 /* config.xml */, ); @@ -339,6 +349,7 @@ ); name = PenguinWidgetExtension; packageProductDependencies = ( + 3A20895925C26EFB001D7490 /* Alamofire */, ); productName = PenguinWidgetExtension; productReference = 3A1157AC258F2B5C00F4C6FD /* PenguinWidgetExtension.appex */; @@ -433,6 +444,7 @@ 3A8EFF992599BBC100B6A788 /* alert1.caf in Resources */, 50B271D11FEDC1A000F3C39B /* public in Resources */, 504EC30F1FED79650016851F /* Assets.xcassets in Resources */, + 3A65B09725C662EE00E1AE2A /* LaunchScreen.storyboard in Resources */, 3AA7E33725211FD500387971 /* InfoPlist.strings in Resources */, 50379B232058CBB4000EE86E /* capacitor.config.json in Resources */, 504EC30D1FED79650016851F /* Main.storyboard in Resources */, @@ -488,10 +500,10 @@ buildActionMask = 2147483647; files = ( ); - inputPaths = ( + inputFileListPaths = ( ); name = "[CP] Embed Pods Frameworks"; - outputPaths = ( + outputFileListPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; @@ -506,6 +518,7 @@ buildActionMask = 2147483647; files = ( 3A06C13B25976DAF00B81F31 /* MediumWidgetView.swift in Sources */, + 3A20895D25C2ACC5001D7490 /* Helpers.swift in Sources */, 3A968BB52597A54E005266F2 /* LargeWidgetView.swift in Sources */, 3A06C118259720D600B81F31 /* PenguinWidget.swift in Sources */, 3A5051C1259666FB004167D3 /* ItemStatsView.swift in Sources */, @@ -515,8 +528,7 @@ 3A1157B1258F2B5C00F4C6FD /* SmallWidgetView.swift in Sources */, 3A06C12D2597454600B81F31 /* WidgetFooter.swift in Sources */, 3A06C1252597447200B81F31 /* StageView.swift in Sources */, - 3A06C120259743B900B81F31 /* Helpers.swift in Sources */, - 3A55B6102598D9F500699BBA /* Intents.intentdefinition in Sources */, + 3A33A3D925D3DA96001867F0 /* Intents.intentdefinition in Sources */, 3A06C1102597112E00B81F31 /* SiteStats.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -528,6 +540,8 @@ 3A616168259C698B00FA06A2 /* NotificationPreferences.swift in Sources */, 3A885ACE25A443D600247AED /* EventBus.swift in Sources */, 3A55B6842599056000699BBA /* Constants.swift in Sources */, + 3A3F035B25C0B3D000DEED16 /* PersistenceManager.swift in Sources */, + 3A33A3D825D3DA96001867F0 /* Intents.intentdefinition in Sources */, 3A001AD32599A4A60078A265 /* ConsentView.swift in Sources */, 3A001AC225991E2C0078A265 /* WhatsNew.swift in Sources */, 3A679B012599166C00A685E9 /* WelcomeView.swift in Sources */, @@ -535,9 +549,9 @@ 3A61616C259C7B8D00FA06A2 /* HapticButton.swift in Sources */, 3A001AD72599A68A0078A265 /* Helpers.swift in Sources */, 3AA7E3462521F70B00387971 /* PenguinPlugin.m in Sources */, + 3A0C886325C25E8E008E1F4B /* PushManager.swift in Sources */, 3A4D4431259AC0BA000807F8 /* InitialLaunch.swift in Sources */, 504EC3081FED79650016851F /* AppDelegate.swift in Sources */, - 3A55B60F2598D9F500699BBA /* Intents.intentdefinition in Sources */, 3AA7E3422521F6C000387971 /* PenguinPlugin.swift in Sources */, 3A616162259B2D2D00FA06A2 /* Debugger.swift in Sources */, ); @@ -554,6 +568,15 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 3A33A3DB25D3DA96001867F0 /* Intents.intentdefinition */ = { + isa = PBXVariantGroup; + children = ( + 3A33A3DA25D3DA96001867F0 /* en */, + 3A33A3DF25D3DAA2001867F0 /* zh-Hans */, + ); + name = Intents.intentdefinition; + sourceTree = ""; + }; 3A5051AC25965532004167D3 /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( @@ -563,12 +586,12 @@ name = Localizable.strings; sourceTree = ""; }; - 3A55B6132598D9F500699BBA /* Intents.intentdefinition */ = { + 3A65B09525C662EE00E1AE2A /* LaunchScreen.storyboard */ = { isa = PBXVariantGroup; children = ( - 3A885ABF25A0157A00247AED /* en */, + 3A65B09625C662EE00E1AE2A /* Base */, ); - name = Intents.intentdefinition; + name = LaunchScreen.storyboard; sourceTree = ""; }; 3AA7E33925211FD500387971 /* InfoPlist.strings */ = { @@ -602,7 +625,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CODE_SIGN_ENTITLEMENTS = PenguinWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = SY8Y8N4TPM; INFOPLIST_FILE = PenguinWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -611,7 +634,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.4.1; + MARKETING_VERSION = 3.4.2; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.penguinstats.app.PenguinWidget; @@ -634,7 +657,7 @@ CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; CODE_SIGN_ENTITLEMENTS = PenguinWidgetExtension.entitlements; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 3; + CURRENT_PROJECT_VERSION = 2; DEVELOPMENT_TEAM = SY8Y8N4TPM; INFOPLIST_FILE = PenguinWidget/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 14.0; @@ -643,7 +666,7 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 3.4.1; + MARKETING_VERSION = 3.4.2; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = io.penguinstats.app.PenguinWidget; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -782,7 +805,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.4.1; + MARKETING_VERSION = 3.4.2; OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\""; PRODUCT_BUNDLE_IDENTIFIER = io.penguinstats.app; PRODUCT_NAME = "$(TARGET_NAME)"; @@ -814,7 +837,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.4.1; + MARKETING_VERSION = 3.4.2; PRODUCT_BUNDLE_IDENTIFIER = io.penguinstats.app; PRODUCT_NAME = "$(TARGET_NAME)"; SUPPORTS_MACCATALYST = NO; @@ -878,6 +901,11 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ + 3A20895925C26EFB001D7490 /* Alamofire */ = { + isa = XCSwiftPackageProductDependency; + package = 3A8EFF9E259A1BB900B6A788 /* XCRemoteSwiftPackageReference "Alamofire" */; + productName = Alamofire; + }; 3A885AC925A43F0400247AED /* RxBus */ = { isa = XCSwiftPackageProductDependency; package = 3A885AC825A43F0400247AED /* XCRemoteSwiftPackageReference "RxBus-Swift" */; diff --git a/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..daa1f171 --- /dev/null +++ b/ios/App/App.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,34 @@ +{ + "object": { + "pins": [ + { + "package": "Alamofire", + "repositoryURL": "https://github.com/Alamofire/Alamofire", + "state": { + "branch": null, + "revision": "eaf6e622dd41b07b251d8f01752eab31bc811493", + "version": "5.4.1" + } + }, + { + "package": "RxBus", + "repositoryURL": "https://github.com/ridi/RxBus-Swift", + "state": { + "branch": null, + "revision": "542c47d46682a64867315867f45403a616ca40b0", + "version": "1.3.1" + } + }, + { + "package": "RxSwift", + "repositoryURL": "https://github.com/ReactiveX/RxSwift.git", + "state": { + "branch": null, + "revision": "002d325b0bdee94e7882e1114af5ff4fe1e96afa", + "version": "5.1.1" + } + } + ] + }, + "version": 1 +} diff --git a/ios/App/App/AppDelegate.swift b/ios/App/App/AppDelegate.swift index 505580fd..24d440e7 100644 --- a/ios/App/App/AppDelegate.swift +++ b/ios/App/App/AppDelegate.swift @@ -6,6 +6,7 @@ import Network import RxBus import RxSwift +import os let alreadyLaunchedKey = "alreadyLaunched" @@ -23,7 +24,6 @@ class SheetDismisserProtocol: ObservableObject { class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? var shortcutItemToProcess: UIApplicationShortcutItem? -// var db: SQLite.Connection? func navigateTo(_ path: String) { guard var components = URLComponents(string: "https://penguin-stats.io/") else { return } @@ -87,7 +87,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if #available(iOS 13.0, *) { let debuggerBtn = UIButton(frame: CGRect( x: UIScreen.main.bounds.maxX - 80 - 18, - y: UIScreen.main.bounds.maxY - 36 - 72, + y: UIScreen.main.bounds.maxY - 36 - 108, width: 80, height: 36 )) @@ -102,10 +102,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate { debuggerBtn.layer.shadowOpacity = 0.8 debuggerBtn.layer.shouldRasterize = true debuggerBtn.layer.rasterizationScale = UIScreen.main.scale - + let gesture = UITapGestureRecognizer(target: self, action: #selector(self.openDebugger)) debuggerBtn.addGestureRecognizer(gesture) - + root?.view.addSubview(debuggerBtn) } #endif @@ -130,6 +130,46 @@ class AppDelegate: UIResponder, UIApplicationDelegate { monitor.start(queue: DispatchQueue.global(qos: .background)) } + if let options = launchOptions { + let notif = options[UIApplication.LaunchOptionsKey.remoteNotification] as? [NSDictionary] + print("remote notification launch option", notif ?? "null") + } + + #if DEBUG + + // MARK: CSSearchableItemAttributeSet for CSSearchableItem + + var searchableItemAttributeSet: CSSearchableItemAttributeSet + if #available(iOS 14.0, *) { + searchableItemAttributeSet = CSSearchableItemAttributeSet(contentType: .url) + } else { + searchableItemAttributeSet = CSSearchableItemAttributeSet() + } + + + let url = URL(string: "https://penguin-stats.io/report") + searchableItemAttributeSet.url = url + searchableItemAttributeSet.title = "PenguinTestReport" + searchableItemAttributeSet.contentDescription = "Penguin Test Report!" + + // MARK: CSSearchableItem + + let item = CSSearchableItem(uniqueIdentifier: "PenguinTest", domainIdentifier: "io.penguinstats.app.PenguinTest", attributeSet: searchableItemAttributeSet) + + CSSearchableIndex.default().deleteAllSearchableItems() + CSSearchableIndex.default().indexSearchableItems([item]) { error in + if let error = error { + print("Indexing error: \(error.localizedDescription)") + } else { + print("Search item successfully indexed!") + } + } + + #endif + + + + return true } @@ -159,6 +199,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func applicationDidBecomeActive(_ application: UIApplication) { // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. + UIApplication.shared.applicationIconBadgeNumber = 0 let root = window?.rootViewController @@ -183,29 +224,28 @@ class AppDelegate: UIResponder, UIApplicationDelegate { if #available(iOS 13.0, *) { let delegate = SheetDismisserProtocol() let welcomeView = InitialLaunch(delegate: delegate) - + let host = UIHostingController(rootView: AnyView(welcomeView)) host.isModalInPresentation = true - + delegate.host = host - + root?.present(host, animated: true, completion: nil) } else { let alertController = UIAlertController( - title: NSLocalizedString("Deprecated iOS", comment: "Title for alerting user their iOS support is deprecated"), - message: NSLocalizedString("Your iOS version is already deprecated and thus may experience problems when using this App.", comment: "Content for alerting user their iOS support is deprecated and may expericence problems"), + title: NSLocalizedString("welcomeDeprecatedTitle", value: "Deprecated iOS", comment: "Title for alerting user their iOS support is deprecated"), + message: NSLocalizedString("welcomeDeprecatedSubtitle", value: "Your iOS version is already deprecated and thus may experience problems when using this App.", comment: "Content for alerting user their iOS support is deprecated and may expericence problems"), preferredStyle: .alert ) let okAction = UIAlertAction( - title: NSLocalizedString("OK", comment: "Button for OK - dismissing dialog"), style: .default) { _ in + title: NSLocalizedString("welcomeDeprecatedConfirm", value: "OK", comment: "Button for OK - dismissing dialog"), style: .default) { _ in UserDefaults.standard.set(true, forKey: alreadyLaunchedKey) } alertController.addAction(okAction) root?.present(alertController, animated: true, completion: nil) } } - } func applicationWillTerminate(_ application: UIApplication) { @@ -225,9 +265,17 @@ class AppDelegate: UIResponder, UIApplicationDelegate { // Called when the app was launched with an activity, including Universal Links. // Feel free to add additional processing here, but if you want the App API to support // tracking app url opens, make sure to keep this call - CAPLog.print("application launched with userActivity ", userActivity) + print("application launched with userActivity.debugDesc", userActivity.debugDescription, "type", userActivity.activityType, "contentAttributeSet", userActivity.userInfo, "userInfo", userActivity.userInfo) + print("got userinfo", userActivity.userInfo) - return CAPBridge.handleContinueActivity(userActivity, restorationHandler) + let options: [UIApplication.OpenURLOptionsKey : Any] = [:] + if userActivity.activityType == CSSearchableItemActionType && (userActivity.webpageURL != nil) { + return CAPBridge.handleOpenUrl(userActivity.webpageURL!, options) + } else if userActivity.contentAttributeSet?.url != nil { + return CAPBridge.handleOpenUrl((userActivity.contentAttributeSet?.url)!, options) + } else { + return CAPBridge.handleContinueActivity(userActivity, restorationHandler) + } } override func touchesBegan(_ touches: Set, with event: UIEvent?) { @@ -246,13 +294,20 @@ class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) { CAPLog.print("registered device with deviceToken", deviceToken.hexEncodedString()) NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidRegisterForRemoteNotificationsWithDeviceToken.name()), object: deviceToken) - UserDefaults.standard.set(deviceToken.hexEncodedString(), forKey: "apfsToken") + PushManager.shared.didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: deviceToken) } func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { NotificationCenter.default.post(name: Notification.Name(CAPNotifications.DidFailToRegisterForRemoteNotificationsWithError.name()), object: error) } + func userNotificationCenter(_ center: UNUserNotificationCenter, + willPresent notification: UNNotification, + withCompletionHandler completionHandler: @escaping (UNNotificationPresentationOptions) -> Void) { + print("received remote notification", notification) + completionHandler(.alert) + } + #endif } diff --git a/ios/App/App/en.lproj/LaunchScreen.storyboard b/ios/App/App/Base.lproj/LaunchScreen.storyboard similarity index 100% rename from ios/App/App/en.lproj/LaunchScreen.storyboard rename to ios/App/App/Base.lproj/LaunchScreen.storyboard diff --git a/ios/App/App/EventBus.swift b/ios/App/App/EventBus.swift index d6f3c046..53305153 100644 --- a/ios/App/App/EventBus.swift +++ b/ios/App/App/EventBus.swift @@ -9,14 +9,6 @@ import Foundation import RxBus import RxSwift -//protocol MyEncodable: Encodable { -// func toJSONData() -> Data -//} -// -//extension MyEncodable { -// func toJSONData() -> Data{ try? JSONEncoder().encode(self) } -//} - struct Events { struct NetworkPathChanged: BusEvent, Encodable { let isConstrained: Bool diff --git a/ios/App/App/Helpers.swift b/ios/App/App/Helpers.swift index aee2dd47..48082bb6 100644 --- a/ios/App/App/Helpers.swift +++ b/ios/App/App/Helpers.swift @@ -55,4 +55,86 @@ struct BlurModifierSimple: ViewModifier { } } +public extension String { + func withBundleIdentifier() -> String { + return (Bundle.main.bundleIdentifier ?? "io.penguinstats.app") + "." + self + } +} + +public class Routes { + public static let defaultBaseString = "https://penguin-stats.io/" + public static let defaultBaseURL = URL(string: defaultBaseString)! +// public static let defaultBaseURLComponent = URLComponents(string: defaultBaseString)! + + public static func generate(zoneId: String, stageId: String) -> URL { + guard var component = URLComponents(string: defaultBaseString) else { return defaultBaseURL } + component.path = "/result/stage/\(zoneId)/\(stageId)" + print(component.url ?? defaultBaseURL) + return component.url ?? defaultBaseURL + } + + public static func generate(itemId: String) -> URL { + guard var component = URLComponents(string: defaultBaseString) else { return defaultBaseURL } + component.path = "/result/item/\(itemId)" + + return component.url ?? defaultBaseURL + } + + public static func generate(path: String) -> URL { + guard var component = URLComponents(string: defaultBaseString) else { return defaultBaseURL } + component.path = path + + return component.url ?? defaultBaseURL + } +} + +@available(iOS 13.0, *) +public extension View { + func Print(_ vars: Any...) -> some View { + for v in vars { print(v) } + return EmptyView() + } +} +@available(iOS 12.0, *) +public extension Servers { + func string() -> String { + switch self { + case .cn: + return "CN" + case .us: + return "US" + case .jp: + return "JP" + case .kr: + return "KR" + default: + return "CN" + } + } +} + +public class Localizer { + static let currentLocale = String(Bundle.main.preferredLocalizations.first?.split(separator: "-")[0] ?? "") + static let defaultLocale = "en" + + public static func localized(from i18nMessage: [String: String]) -> String? { + if i18nMessage[currentLocale] != nil { + return i18nMessage[currentLocale] + } else { + return i18nMessage[defaultLocale] + } + } +} + +struct JSON { + static let encoder = JSONEncoder() +} +extension Encodable { + subscript(key: String) -> Any? { + return dictionary[key] + } + var dictionary: [String: Any] { + return (try? JSONSerialization.jsonObject(with: JSON.encoder.encode(self))) as? [String: Any] ?? [:] + } +} diff --git a/ios/App/App/Info.plist b/ios/App/App/Info.plist index b736cc38..c1ae3308 100644 --- a/ios/App/App/Info.plist +++ b/ios/App/App/Info.plist @@ -33,6 +33,10 @@ CFBundleVersion $(CURRENT_PROJECT_VERSION) + INIntentsSupported + + SelectServerIntent + LSRequiresIPhoneOS NSAllowsLocalNetworking diff --git a/ios/App/App/PenguinPlugin.m b/ios/App/App/PenguinPlugin.m index 8720e9ca..0243bc82 100644 --- a/ios/App/App/PenguinPlugin.m +++ b/ios/App/App/PenguinPlugin.m @@ -12,4 +12,10 @@ CAP_PLUGIN_METHOD(getLocalizationEnvironment, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(getRegion, CAPPluginReturnPromise); CAP_PLUGIN_METHOD(hapticsGeneral, CAPPluginReturnNone); - ) + CAP_PLUGIN_METHOD(updateSpotlightItems, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(updateCurrentUserActivity, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(openBundleSettings, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(getLastSyncedPushPreferences, CAPPluginReturnPromise); + CAP_PLUGIN_METHOD(submitNewPushPreferences, CAPPluginReturnPromise); + +) diff --git a/ios/App/App/PenguinPlugin.swift b/ios/App/App/PenguinPlugin.swift index 81bf17f3..ba912713 100644 --- a/ios/App/App/PenguinPlugin.swift +++ b/ios/App/App/PenguinPlugin.swift @@ -13,6 +13,7 @@ import CoreHaptics @objc(PenguinPlugin) public class PenguinPlugin: CAPPlugin { + let currentUserActivityKey = "CurrentUserActivity" @objc func listenerReady(_ call: CAPPluginCall) { RxBus.shared.asObservable(event: Events.NetworkPathChanged.self, sticky: true).subscribe { event in @@ -40,25 +41,183 @@ public class PenguinPlugin: CAPPlugin { } @objc func getLocalizationEnvironment(_ call: CAPPluginCall) { - let jsonEncoder = JSONEncoder() - let jsonData = try! jsonEncoder.encode(NSLocale.current.identifier) - let json = String(data: jsonData, encoding: String.Encoding.utf8) - call.success([ - "locale": json! + "locale": NSLocale.current.identifier ]) } @objc func getRegion(_ call: CAPPluginCall) { - let jsonEncoder = JSONEncoder() - let jsonData = try! jsonEncoder.encode(Locale.current.regionCode) - let json = String(data: jsonData, encoding: String.Encoding.utf8) - call.success([ - "region": json! + "region": Locale.current.regionCode ]) } + @objc func updateSpotlightItems(_ call: CAPPluginCall) { + guard let items = call.getArray("items", [String: Any].self) else { + call.error("Missing required parameter `items`") + return + } + + let indexName = call.getString("spotlightIndexName") ?? "penguinDefault" + + let queue = DispatchQueue.init(label: "SpotlightDispatchQueue", qos: .utility, attributes: .initiallyInactive, autoreleaseFrequency: .inherit, target: .main) + + queue.async { + let spotlightIndex = CSSearchableIndex.init(name: indexName) + spotlightIndex.deleteAllSearchableItems { error in + spotlightIndex.beginBatch() + + for (index, item) in items.enumerated() { + guard let id = item["id"] as? String else { + call.error("Missing required parameter `id` on item index \(index)") + return + } + guard let title = item["title"] as? String else { + call.error("Missing required parameter `title` on item index \(index)") + return + } + guard let description = item["description"] as? String else { + call.error("Missing required parameter `description` on item index \(index)") + return + } + guard let path = item["path"] as? String else { + call.error("Missing required parameter `path` on item index \(index)") + return + } + + var url = URLComponents(string: "https://penguin-stats.io/") + url?.path = path + + let attrs = CSSearchableItemAttributeSet() + attrs.url = url?.url + attrs.title = title + attrs.contentDescription = description + attrs.domainIdentifier = "https://penguin-stats.io" + attrs.downloadedDate = Date() + + spotlightIndex.indexSearchableItems([CSSearchableItem(uniqueIdentifier: id, domainIdentifier: id.withBundleIdentifier(), attributeSet: attrs)]) + } + + spotlightIndex.endBatch(withClientState: Data()) { error in + print("Failed to endBatch with error \(String(describing: error))") + } + } + + call.success() + } + } + + @objc func updateCurrentUserActivity(_ call: CAPPluginCall) { + let id = call.getString("id") ?? "io.penguinstats.app.UndefinedUserActivity" + let title = call.getString("title") + let description = call.getString("description") + let path = call.getString("path") ?? "/" + var urlComponent = URLComponents(string: "https://penguin-stats.io/") + urlComponent?.path = path + let url = urlComponent?.url + + let last = PersistenceManager.shared.getItem(key: currentUserActivityKey) as? NSUserActivity + if last != nil { + last!.invalidate() + } + + // MARK: CSSearchableItemAttributeSet for NSUserActivity + var userActivityAttributeSet: CSSearchableItemAttributeSet + if #available(iOS 14.0, *) { + userActivityAttributeSet = CSSearchableItemAttributeSet(contentType: .url) + } else { + userActivityAttributeSet = CSSearchableItemAttributeSet() + } + userActivityAttributeSet.url = url + userActivityAttributeSet.title = title + userActivityAttributeSet.contentDescription = description + userActivityAttributeSet.domainIdentifier = id + userActivityAttributeSet.contentModificationDate = Date() + + // MARK: NSUserActivity + let activity = NSUserActivity(activityType: id) + activity.isEligibleForHandoff = true + if #available(iOS 12.0, *) { + activity.isEligibleForPrediction = true + } + activity.webpageURL = url + activity.requiredUserInfoKeys = Set([]) + activity.contentAttributeSet = userActivityAttributeSet + activity.title = title + PersistenceManager.shared.setItem(activity, forKey: currentUserActivityKey) + activity.becomeCurrent() + + call.success() + } + + @objc func openBundleSettings(_ call: CAPPluginCall) { + guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else { + call.error("failed to initialize url instance") + return + } + + DispatchQueue.main.async { + UIApplication.shared.open(settingsUrl) { (success) in + print("Bundle settings opened?: \(success)") + if success { + call.success() + } else { + call.error("failed to open bundle settings") + } + } + } + } + + @objc func getLastSyncedPushPreferences(_ call: CAPPluginCall) { + guard let preferences = PushManager.shared.getLastSyncedPushPreferences() else { + call.success([ + "preferences": [] + ]) + return + } + print(preferences) + do { + let json = try JSONEncoder().encode(preferences).toString() ?? "" + print(json) + call.success([ + "preferences": json + ]) + } catch { + call.reject("failed to serialize message", error.localizedDescription) + print("failed to serialize message", error) + return + } + } + + @objc func submitNewPushPreferences(_ call: CAPPluginCall) { + guard let preferences = call.getArray("preferences", [String: Any].self) else { + call.error("Missing required parameter `preferences`") + return + } + + var unmarshalled: [Preference] = [] + + for (index, preference) in preferences.enumerated() { + guard let locale = preference["locale"] as? String else { + call.error("Missing required parameter `locale` on item index \(index)") + return + } + guard let server = preference["server"] as? String else { + call.error("Missing required parameter `server` on item index \(index)") + return + } + guard let category = preference["category"] as? String else { + call.error("Missing required parameter `category` on item index \(index)") + return + } + + unmarshalled.append(Preference(locale: locale, server: server, category: category)) + } + + PushManager.shared.register(with: unmarshalled) + call.success() + } + // @objc func addSearchableItem(_ call: CAPPluginCall) { // let item = call.getObject("item") // diff --git a/ios/App/App/Repositories/PersistenceManager.swift b/ios/App/App/Repositories/PersistenceManager.swift new file mode 100644 index 00000000..139459bc --- /dev/null +++ b/ios/App/App/Repositories/PersistenceManager.swift @@ -0,0 +1,36 @@ +// +// PersistenceManager.swift +// App +// +// Created by Galvin Gao on 2021/1/27. +// + +import Foundation + +class PersistenceManager { + public static let shared = PersistenceManager() + + var values: [Any] + var namedValues: [String: Any] + + init() { + self.values = [] + self.namedValues = [:] + } + + public func addItem(_ item: Any) { + self.values.append(item) + } + + public func setItem(_ value: Any, forKey key: String) { + self.namedValues[key] = value + } + + public func removeItem(_ at: Int) { + self.values.remove(at: at) + } + + public func getItem(key: String) -> Any { + return self.namedValues[key] ?? "" + } +} diff --git a/ios/App/App/Repositories/PushManager.swift b/ios/App/App/Repositories/PushManager.swift new file mode 100644 index 00000000..7b637bf4 --- /dev/null +++ b/ios/App/App/Repositories/PushManager.swift @@ -0,0 +1,107 @@ +// +// ConfigManager.swift +// App +// +// Created by Galvin Gao on 2021/1/28. +// + +import Foundation +import Alamofire + +struct Preference: Codable { + var locale: String + var server: String + var category: String +} + +struct RegistrationRequest: Codable { + var deviceToken: String + var platform: String + var preferences: [Preference] +} + +class PushManager { + public static let shared = PushManager() + + let lastSyncedDeviceTokenKey = "push.lastSuccessfullySyncedDeviceToken".withBundleIdentifier() + let lastSyncedPushPreferencesKey = "push.lastSuccessfullySyncedPushPreferences".withBundleIdentifier() + + var stalePreferences: [Preference]? + + private func pushSubscriptionDidSucceeded(for token: String, with preferences: [Preference]) { + UserDefaults.standard.set(token, forKey: lastSyncedDeviceTokenKey) + + do { + let encoded = try JSONEncoder().encode(preferences).toString() ?? "" + UserDefaults.standard.set(encoded, forKey: lastSyncedPushPreferencesKey) + } catch { print(error) } + } + + public func getLastSyncedPushPreferences() -> [Preference]? { + guard let preferences = UserDefaults.standard.string(forKey: lastSyncedPushPreferencesKey)?.data(using: .utf8) else { + return nil + } + + do { + let decoded = try JSONDecoder().decode([Preference].self, from: preferences) + return decoded + } catch { print(error) } + + return nil + } + + public func register(with preferences: [Preference]) { + let lastToken = UserDefaults.standard.string(forKey: lastSyncedDeviceTokenKey) + if lastToken == nil { + self.stalePreferences = preferences + return + } + self.register(for: lastToken!, with: preferences) + } + + private func register(for token: String, with preferences: [Preference]?) { + let pref = preferences ?? [] + let params = RegistrationRequest.init(deviceToken: token, platform: "IOS", preferences: pref) + +// let jsonString = String(data: jsonData, encoding: .utf8)! + + #if DEBUG + + AF.request("http://10.6.6.150:8105/registration", method: .put, parameters: params.dictionary, encoding: JSONEncoding.default, headers: [HTTPHeader(name: "Content-Type", value: "application/json")]).response { (response) in + if let error = response.error { + print("registration error", error) + return + } + print("registered with param", params, "with response", response.data?.toString() ?? "nil") + self.pushSubscriptionDidSucceeded(for: token, with: pref) + } + + #endif + } + + private func revokeToken(for token: String) { + AF.request("http://10.6.6.150:8105/registration/" + token, method: .delete).response { (response) in + print("revoked token", response) + } + } + + public func didRegisterForRemoteNotificationsWithDeviceToken(deviceToken: Data) { + let lastToken = UserDefaults.standard.string(forKey: lastSyncedDeviceTokenKey) + let currentToken = deviceToken.hexEncodedString() + + print("lastToken", lastToken ?? "nil", "currentToken", currentToken) + + #if DEBUG + + if lastToken != currentToken { + // token changed. revoke last one if have any, and start registering for new one + if lastToken != nil { + self.revokeToken(for: lastToken!) + } + + self.register(for: currentToken, with: self.stalePreferences) + } + + #endif + } +} diff --git a/ios/App/App/Views/ConsentView.swift b/ios/App/App/Views/ConsentView.swift index bc5e3f1a..3b2d4b81 100644 --- a/ios/App/App/Views/ConsentView.swift +++ b/ios/App/App/Views/ConsentView.swift @@ -43,7 +43,6 @@ struct ConsentView: View { .padding(.top) } .padding() - .padding(.top) List { ToggleNotificationPreference( diff --git a/ios/App/App/Views/Debugger.swift b/ios/App/App/Views/Debugger.swift index 4601f813..ee0aeb3b 100644 --- a/ios/App/App/Views/Debugger.swift +++ b/ios/App/App/Views/Debugger.swift @@ -71,7 +71,9 @@ struct Debugger: View { .buttonStyle(GenericButtonStyle()) } .navigationBarTitle("Debugger") + } + .navigationViewStyle(StackNavigationViewStyle()) } } diff --git a/ios/App/App/Views/InitialLaunch.swift b/ios/App/App/Views/InitialLaunch.swift index fce130ec..4c765513 100644 --- a/ios/App/App/Views/InitialLaunch.swift +++ b/ios/App/App/Views/InitialLaunch.swift @@ -20,6 +20,7 @@ struct InitialLaunch: View { .navigationBarTitle("Welcome") .navigationBarHidden(true) } + .navigationViewStyle(StackNavigationViewStyle()) } } diff --git a/ios/App/App/capacitor.config.json b/ios/App/App/capacitor.config.json index 4b755e8f..a40dd97c 100644 --- a/ios/App/App/capacitor.config.json +++ b/ios/App/App/capacitor.config.json @@ -1,7 +1,7 @@ { "appId": "io.penguinstats.app", "appName": "企鹅物流", - "bundledWebRuntime": false, + "bundledWebRuntime": true, "npmClient": "yarn", "webDir": "dist", "plugins": { @@ -9,7 +9,8 @@ "launchAutoHide": false, "backgroundColor": "#000000ff", "showSpinner": true, - "spinnerColor": "#fff" + "spinnerColor": "#fff", + "splashFullScreen": true }, "PushNotifications": { "presentationOptions": ["badge", "sound", "alert"] diff --git a/ios/App/App/config.xml b/ios/App/App/config.xml index 1b1b0e0d..4314fe6f 100644 --- a/ios/App/App/config.xml +++ b/ios/App/App/config.xml @@ -1,4 +1,4 @@ - + diff --git a/ios/App/PenguinWidget/ExternalService.swift b/ios/App/PenguinWidget/ExternalService.swift index ee1a2589..6983f7c7 100644 --- a/ios/App/PenguinWidget/ExternalService.swift +++ b/ios/App/PenguinWidget/ExternalService.swift @@ -6,7 +6,59 @@ // import Foundation +import Alamofire -//func (<#parameters#>) -> <#return type#> { -// <#function body#> -//} +struct StatsResponse: Decodable { + let stats: [StatsResponseStat] +} + +struct StatsResponseStat: Decodable { + let stage: StatsResponseStatStage + let item: StatsResponseStatItem + let quantity: Int + let times: Int + let recentTimes: Int +} + +struct StatsResponseStatStage: Decodable { + let zoneId: String + let stageId: String + let code_i18n: [String: String] +} + +struct StatsResponseStatItem: Decodable { + let itemId: String + let name_i18n: [String: String] +} + +func getStats(for server: Servers, completion: @escaping (SiteStats?) -> ()) { + AF.request("https://widget.penguin-stats.io/api/stats/" + server.string(), requestModifier: { + $0.timeoutInterval = TimeInterval(25.0) // system give us 30s. make some room + }).response {resp in + guard let data = resp.data else { + completion(nil) + return + } + + let stats: StatsResponse = try! JSONDecoder().decode(StatsResponse.self, from: data) + + var stages: [StageStats] = []; + + for stat in stats.stats { + let item = ItemStats.init(id: stat.item.itemId, + name: Localizer.localized(from: stat.item.name_i18n) ?? "unknown", + times: stat.times, quantity: stat.quantity) + + let stage = StageStats.init(stageId: stat.stage.stageId, + zoneId: stat.stage.zoneId, + stageCode: Localizer.localized(from: stat.stage.code_i18n) ?? "unknown", + items: [item], + recentTimes: stat.recentTimes) + stages.append(stage) + } + + let siteStats = SiteStats.init(stages: stages, server: server) + + completion(siteStats) + } +} diff --git a/ios/App/PenguinWidget/Helpers.swift b/ios/App/PenguinWidget/Helpers.swift deleted file mode 100644 index 57577a7f..00000000 --- a/ios/App/PenguinWidget/Helpers.swift +++ /dev/null @@ -1,17 +0,0 @@ -// -// Helpers.swift -// PenguinWidgetExtension -// -// Created by Galvin Gao on 2020/12/26. -// - -import Foundation -import WidgetKit -import SwiftUI - -extension View { - func Print(_ vars: Any...) -> some View { - for v in vars { print(v) } - return EmptyView() - } -} diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/Contents.json old mode 100755 new mode 100644 index 73c00596..65af1f21 --- a/ios/App/PenguinWidget/ItemIcons.xcassets/Contents.json +++ b/ios/App/PenguinWidget/ItemIcons.xcassets/Contents.json @@ -1,6 +1,6 @@ { - "info" : { - "author" : "xcode", - "version" : 1 - } -} + "info": { + "author": "xcode", + "version": 1 + } +} \ No newline at end of file diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2001.imageset/2001.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2001.imageset/2001.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2001.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2001.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2002.imageset/2002.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2002.imageset/2002.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2002.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2002.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2003.imageset/2003.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2003.imageset/2003.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2003.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2003.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2004.imageset/2004.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2004.imageset/2004.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_2004.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_2004.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30011.imageset/30011.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30011.imageset/30011.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30011.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30011.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30012.imageset/30012.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30012.imageset/30012.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30012.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30012.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30013.imageset/30013.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30013.imageset/30013.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30013.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30013.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30014.imageset/30014.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30014.imageset/30014.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30014.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30014.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30021.imageset/30021.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30021.imageset/30021.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30021.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30021.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30022.imageset/30022.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30022.imageset/30022.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30022.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30022.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30023.imageset/30023.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30023.imageset/30023.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30023.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30023.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30024.imageset/30024.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30024.imageset/30024.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30024.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30024.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30031.imageset/30031.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30031.imageset/30031.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30031.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30031.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30032.imageset/30032.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30032.imageset/30032.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30032.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30032.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30033.imageset/30033.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30033.imageset/30033.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30033.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30033.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30034.imageset/30034.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30034.imageset/30034.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30034.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30034.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30041.imageset/30041.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30041.imageset/30041.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30041.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30041.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30042.imageset/30042.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30042.imageset/30042.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30042.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30042.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30043.imageset/30043.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30043.imageset/30043.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30043.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30043.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30044.imageset/30044.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30044.imageset/30044.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30044.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30044.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30051.imageset/30051.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30051.imageset/30051.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30051.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30051.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30052.imageset/30052.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30052.imageset/30052.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30052.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30052.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30053.imageset/30053.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30053.imageset/30053.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30053.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30053.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30054.imageset/30054.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30054.imageset/30054.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30054.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30054.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30061.imageset/30061.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30061.imageset/30061.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30061.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30061.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30062.imageset/30062.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30062.imageset/30062.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30062.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30062.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30063.imageset/30063.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30063.imageset/30063.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30063.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30063.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30064.imageset/30064.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30064.imageset/30064.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30064.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30064.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30073.imageset/30073.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30073.imageset/30073.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30073.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30073.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30074.imageset/30074.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30074.imageset/30074.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30074.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30074.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30083.imageset/30083.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30083.imageset/30083.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30083.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30083.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30084.imageset/30084.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30084.imageset/30084.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30084.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30084.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30093.imageset/30093.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30093.imageset/30093.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30093.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30093.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30094.imageset/30094.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30094.imageset/30094.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30094.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30094.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30103.imageset/30103.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30103.imageset/30103.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30103.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30103.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30104.imageset/30104.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30104.imageset/30104.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30104.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30104.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30115.imageset/30115.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30115.imageset/30115.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30115.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30115.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30125.imageset/30125.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30125.imageset/30125.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30125.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30125.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30135.imageset/30135.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30135.imageset/30135.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30135.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30135.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30145.imageset/30145.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30145.imageset/30145.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_30145.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_30145.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31013.imageset/31013.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31013.imageset/31013.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31013.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31013.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31014.imageset/31014.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31014.imageset/31014.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31014.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31014.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31023.imageset/31023.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31023.imageset/31023.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31023.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31023.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31024.imageset/31024.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31024.imageset/31024.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31024.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31024.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31033.imageset/31033.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31033.imageset/31033.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31033.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31033.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31034.imageset/31034.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31034.imageset/31034.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_31034.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_31034.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3211.imageset/3211.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3211.imageset/3211.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3211.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3211.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3212.imageset/3212.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3212.imageset/3212.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3212.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3212.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3221.imageset/3221.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3221.imageset/3221.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3221.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3221.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3222.imageset/3222.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3222.imageset/3222.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3222.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3222.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3231.imageset/3231.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3231.imageset/3231.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3231.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3231.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3232.imageset/3232.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3232.imageset/3232.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3232.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3232.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3241.imageset/3241.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3241.imageset/3241.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3241.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3241.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3242.imageset/3242.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3242.imageset/3242.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3242.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3242.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3251.imageset/3251.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3251.imageset/3251.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3251.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3251.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3252.imageset/3252.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3252.imageset/3252.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3252.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3252.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3261.imageset/3261.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3261.imageset/3261.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3261.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3261.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3262.imageset/3262.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3262.imageset/3262.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3262.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3262.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3271.imageset/3271.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3271.imageset/3271.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3271.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3271.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3272.imageset/3272.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3272.imageset/3272.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3272.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3272.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3281.imageset/3281.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3281.imageset/3281.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3281.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3281.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3282.imageset/3282.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3282.imageset/3282.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3282.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3282.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3301.imageset/3301.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3301.imageset/3301.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3301.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3301.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3302.imageset/3302.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3302.imageset/3302.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3302.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3302.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3303.imageset/3303.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3303.imageset/3303.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_3303.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_3303.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/Contents.json new file mode 100644 index 00000000..a2118eb5 --- /dev/null +++ b/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images": [ + { + "filename": "furni.png", + "idiom": "universal", + "scale": "1x" + }, + { + "filename": "furni.png", + "idiom": "universal", + "scale": "2x" + }, + { + "filename": "furni.png", + "idiom": "universal", + "scale": "3x" + } + ], + "info": { + "author": "xcode", + "version": 1 + } +} \ No newline at end of file diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/furni.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/furni.png new file mode 100644 index 00000000..59584750 Binary files /dev/null and b/ios/App/PenguinWidget/ItemIcons.xcassets/item_furni.imageset/furni.png differ diff --git a/public/robots.txt b/ios/App/PenguinWidget/ItemIcons.xcassets/item_itemIdImages.imageset/itemIdImages similarity index 100% rename from public/robots.txt rename to ios/App/PenguinWidget/ItemIcons.xcassets/item_itemIdImages.imageset/itemIdImages diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_1.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_1.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_1.imageset/randomMaterial_1.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_1.imageset/randomMaterial_1.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_2.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_2.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_2.imageset/randomMaterial_2.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_2.imageset/randomMaterial_2.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_3.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_3.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_3.imageset/randomMaterial_3.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_3.imageset/randomMaterial_3.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_4.imageset/Contents.json b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_4.imageset/Contents.json old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_4.imageset/randomMaterial_4.png b/ios/App/PenguinWidget/ItemIcons.xcassets/item_randomMaterial_4.imageset/randomMaterial_4.png old mode 100755 new mode 100644 diff --git a/ios/App/PenguinWidget/SiteStats.swift b/ios/App/PenguinWidget/SiteStats.swift index a528beaf..af34f3c5 100644 --- a/ios/App/PenguinWidget/SiteStats.swift +++ b/ios/App/PenguinWidget/SiteStats.swift @@ -27,8 +27,10 @@ struct ItemStats { struct StageStats { let stageId: String + let zoneId: String let stageCode: String let items: [ItemStats] + let recentTimes: Int } enum DemoType { @@ -40,7 +42,7 @@ enum DemoType { struct SiteStats { let stages: [StageStats] - let totalSanity: Int + let server: Servers static func demo(_ type: DemoType) -> SiteStats { switch type { @@ -49,6 +51,7 @@ struct SiteStats { stages: [ StageStats( stageId: "main-01_07", + zoneId: "unknown", stageCode: "1-7", items: [ ItemStats( @@ -57,10 +60,12 @@ struct SiteStats { times: 329752, quantity: 265096 ) - ] + ], + recentTimes: 300 ), StageStats( stageId: "main-04_0112", + zoneId: "unknown", stageCode: "1-8", items: [ ItemStats( @@ -69,10 +74,12 @@ struct SiteStats { times: 324534, quantity: 3425234 ) - ] + ], + recentTimes: 300 ), StageStats( stageId: "main-08_0421", + zoneId: "unknown", stageCode: "4-8", items: [ ItemStats( @@ -81,15 +88,17 @@ struct SiteStats { times: 454532, quantity: 462256 ) - ] + ], + recentTimes: 300 ) ], - totalSanity: 27860888 + server: .cn ) case .zhExtraLong: return SiteStats( stages: Array(repeating: StageStats( stageId: "main-01_07", + zoneId: "unknown", stageCode: "达拉崩吧班得贝迪苏打麻辣香锅卜多比鲁翁", items: [ ItemStats( @@ -98,14 +107,16 @@ struct SiteStats { times: 453234, quantity: 324523 ) - ] + ], + recentTimes: 300 ), count: 3), - totalSanity: 27860888 + server: .cn ) case .enRegular: return SiteStats( stages: Array(repeating: StageStats( stageId: "main-01_07", + zoneId: "unknown", stageCode: "4-8", items: [ ItemStats( @@ -114,14 +125,17 @@ struct SiteStats { times: 2343433, quantity: 1234123 ) - ] + ], + recentTimes: 300 ), count: 3), - totalSanity: 27860888 + server: .cn + ) case .enExtraLong: return SiteStats( stages: Array(repeating: StageStats( stageId: "main-01_07", + zoneId: "unknown", stageCode: "Never gonna give you up", items: [ ItemStats( @@ -130,9 +144,10 @@ struct SiteStats { times: 453234, quantity: 324523 ) - ] + ], + recentTimes: 300 ), count: 3), - totalSanity: 27860888 + server: .cn ) } } diff --git a/ios/App/PenguinWidget/Sizes/LargeWidgetView.swift b/ios/App/PenguinWidget/Sizes/LargeWidgetView.swift index b02159ba..89bfb27c 100644 --- a/ios/App/PenguinWidget/Sizes/LargeWidgetView.swift +++ b/ios/App/PenguinWidget/Sizes/LargeWidgetView.swift @@ -22,7 +22,7 @@ struct LargeWidgetView: View { .padding(.horizontal, 8) Spacer() - WidgetFooter() + WidgetFooter(server: stats.server) } .padding() .background(Color("Background")) diff --git a/ios/App/PenguinWidget/Sizes/MediumWidgetView.swift b/ios/App/PenguinWidget/Sizes/MediumWidgetView.swift index 245040c2..ee884725 100644 --- a/ios/App/PenguinWidget/Sizes/MediumWidgetView.swift +++ b/ios/App/PenguinWidget/Sizes/MediumWidgetView.swift @@ -21,9 +21,8 @@ struct MediumWidgetView: View { TwoColumnStageStats(stages: stats.stages) .padding(.horizontal, 8) - Spacer() - WidgetFooter() + WidgetFooter(server: stats.server) } .padding() .background(Color("Background")) diff --git a/ios/App/PenguinWidget/Sizes/SmallWidgetView.swift b/ios/App/PenguinWidget/Sizes/SmallWidgetView.swift index 096ef129..aefeb195 100644 --- a/ios/App/PenguinWidget/Sizes/SmallWidgetView.swift +++ b/ios/App/PenguinWidget/Sizes/SmallWidgetView.swift @@ -22,10 +22,13 @@ struct SmallWidgetView : View { ItemStatsView(item: stats.stages[0].items[0]) // .frame(minHeight: 0, maxHeight: 28) Spacer() - WidgetFooter() + WidgetFooter(server: stats.server) } .padding() .background(Color("Background")) + .widgetURL(Routes.generate( + zoneId: stats.stages[0].zoneId, + stageId: stats.stages[0].stageId)) } } diff --git a/ios/App/PenguinWidget/Views/ItemStatsView.swift b/ios/App/PenguinWidget/Views/ItemStatsView.swift index f05f5b1f..2b02bc7f 100644 --- a/ios/App/PenguinWidget/Views/ItemStatsView.swift +++ b/ios/App/PenguinWidget/Views/ItemStatsView.swift @@ -11,24 +11,27 @@ import UIKit struct ItemStatsView: View { var item: ItemStats - var showName: Bool = true + var showName: Bool = false var body: some View { HStack(alignment: .center, spacing: 4) { - item.image() - .resizable() - .frame(width: 20, height: 20, alignment: .center) - - if showName { - Text(item.name) - .font(.caption) - .bold() - .lineLimit(2) - .minimumScaleFactor(0.6) - .foregroundColor(Color("Gray5")) + Link(destination: Routes.generate(itemId: item.id)) { + Group { + item.image() + .resizable() + .frame(width: 20, height: 20, alignment: .center) + + if showName { + Text(item.name) + .font(.caption) + .bold() + .lineLimit(2) + .minimumScaleFactor(0.6) + .foregroundColor(Color("Gray5")) + } + } } - Text(item.percentage()) .font(.custom("Bender", size: 12, relativeTo: .body)) .baselineOffset(-1.0) diff --git a/ios/App/PenguinWidget/Views/StageView.swift b/ios/App/PenguinWidget/Views/StageView.swift index 45aa30c4..032a7015 100644 --- a/ios/App/PenguinWidget/Views/StageView.swift +++ b/ios/App/PenguinWidget/Views/StageView.swift @@ -11,27 +11,50 @@ import UIKit struct StageView: View { var stage: StageStats + var showRecentTimes: Bool = false var body: some View { - HStack(alignment: .center, spacing: 4) { - Image(systemName: "cube") - .font(.headline) - .foregroundColor(Color("Gray4")) - .unredacted() - - Text(stage.stageCode) - .font(.title) - .bold() - .frame(minHeight: 0, maxHeight: 36) - .minimumScaleFactor(0.3) - .lineLimit(3) + Link(destination: Routes.generate(zoneId: stage.zoneId, stageId: stage.stageId)) { + + HStack(alignment: .center, spacing: 4) { + Image(systemName: "cube") + .font(.headline) + .foregroundColor(Color("Gray4")) + .unredacted() + + HStack(alignment: .center, spacing: 6) { + Text(stage.stageCode) + .font(.title) + .bold() + .frame(minHeight: 0, maxHeight: 36) + .minimumScaleFactor(0.3) + .lineLimit(3) + .unredacted() + + if showRecentTimes { + Text("× " + String(stage.recentTimes)) + .minimumScaleFactor(0.5) + .lineLimit(1) + .font(.caption) + .foregroundColor(Color("Gray4").opacity(0.8)) + } + } + } } + } } struct StageView_Previews: PreviewProvider { static var previews: some View { - StageView(stage: StageStats(stageId: "main_01-07", stageCode: "1-7", items: [])) + StageView( + stage: StageStats( + stageId: "main_01-07", + zoneId: "unknown", + stageCode: "1-7", + items: [], + recentTimes: 300), + showRecentTimes: true) .previewContext(WidgetPreviewContext(family: .systemSmall)) } } diff --git a/ios/App/PenguinWidget/Views/TwoColumnStageStats.swift b/ios/App/PenguinWidget/Views/TwoColumnStageStats.swift index 62fb9318..9191e153 100644 --- a/ios/App/PenguinWidget/Views/TwoColumnStageStats.swift +++ b/ios/App/PenguinWidget/Views/TwoColumnStageStats.swift @@ -14,12 +14,12 @@ struct TwoColumnStageStats: View { var body: some View { VStack(alignment: .leading, spacing: 4) { ForEach(stages, id: \.stageId) {stage in - HStack(spacing: 16) { - StageView(stage: stage) - .frame(width: 140, alignment: .leading) + HStack(alignment: .center, spacing: 16) { + StageView(stage: stage, showRecentTimes: true) + .frame(width: 125, alignment: .leading) .fixedSize(horizontal: true, vertical: false) - ItemStatsView(item: stage.items[0], showName: false) + ItemStatsView(item: stage.items[0], showName: true) } } } diff --git a/ios/App/PenguinWidget/Views/WidgetFooter.swift b/ios/App/PenguinWidget/Views/WidgetFooter.swift index 12300e05..50dcd9fd 100644 --- a/ios/App/PenguinWidget/Views/WidgetFooter.swift +++ b/ios/App/PenguinWidget/Views/WidgetFooter.swift @@ -6,22 +6,32 @@ // import SwiftUI +import WidgetKit struct WidgetFooter: View { + let server: Servers + var body: some View { - HStack { - HStack(spacing: 4) { - Text("WidgetViewMore") - .bold() - Image(systemName: "arrow.up.forward.app") + HStack(spacing: 4) { + Link(destination: Routes.generate(path: "/statistics")) { + HStack(spacing: 4) { + Text("WidgetViewMore") + .bold() + Image(systemName: "arrow.up.forward.app") + } + .font(.system(size: 11)) + .foregroundColor(Color("Gray4")) + .padding(4) + .background(Color.gray.opacity(0.1)) + .cornerRadius(4.0) + .unredacted() } - .font(.caption) - .foregroundColor(Color("Gray4")) - .padding(4) - .background(Color.gray.opacity(0.1)) - .cornerRadius(4.0) - + Spacer() + Text(server.string()) + .font(.system(size: 10, design: .monospaced)) + .foregroundColor(Color("Gray4")) + .unredacted() Image("Logo") .resizable() .frame(width: 20, height: 20, alignment: .center) @@ -32,6 +42,7 @@ struct WidgetFooter: View { struct WidgetFooter_Previews: PreviewProvider { static var previews: some View { - WidgetFooter() + WidgetFooter(server: .cn) + .previewContext(WidgetPreviewContext(family: .systemSmall)) } } diff --git a/ios/App/PenguinWidget/WidgetEntry.swift b/ios/App/PenguinWidget/WidgetEntry.swift index 37f5c0ea..9c9e70b5 100644 --- a/ios/App/PenguinWidget/WidgetEntry.swift +++ b/ios/App/PenguinWidget/WidgetEntry.swift @@ -8,13 +8,14 @@ import WidgetKit import SwiftUI import Intents +import Alamofire struct SiteStatsProvider: IntentTimelineProvider { func placeholder(in context: Context) -> WidgetTimelineEntry { - + print("widget placeholder", context) return WidgetTimelineEntry( date: Date(), - stats: SiteStats(stages: [StageStats(stageId: "---", stageCode: "---", items: [ItemStats(id: "---", name: "------", times: 1, quantity: 1)])], totalSanity: 0) + stats: SiteStats.demo(.zhRegular) ) } @@ -29,20 +30,30 @@ struct SiteStatsProvider: IntentTimelineProvider { } func getTimeline(for configuration: SelectServerIntent, in context: Context, completion: @escaping (Timeline) -> ()) { - print("serverSelection timeline", configuration) + print("serverSelection timeline with configured server:", configuration.server.string()) + + print("doing network request") + getStats(for: configuration.server) { (stats) in + + if stats != nil { + print("got stats", stats ?? "undefined") + let entries: [WidgetTimelineEntry] = [ + WidgetTimelineEntry( + date: Date(), + stats: stats! + ) + ] + let timeline = Timeline(entries: entries, policy: .atEnd) + completion(timeline) + } else { + // nothing... + completion(Timeline(entries: [], policy: .atEnd)) + return + } + + } - let entries: [WidgetTimelineEntry] = [ - WidgetTimelineEntry( - date: Date(), - stats: SiteStats.demo(.zhRegular) - ) - ] - - // Generate a timeline consisting of five entries an hour apart, starting from the current date. - - let timeline = Timeline(entries: entries, policy: .atEnd) - completion(timeline) } } @@ -61,10 +72,8 @@ struct WidgetEntry: View { SmallWidgetView(stats: entry.stats) case .systemMedium: MediumWidgetView(stats: entry.stats) -// case .systemLarge: -// LargeWidgetView(stats: entry.stats) default: - fatalError("unrecognized widget family") + MediumWidgetView(stats: entry.stats) } } } diff --git a/ios/App/PenguinWidget/en.lproj/Intents.intentdefinition b/ios/App/PenguinWidget/en.lproj/Intents.intentdefinition index d622aded..00a1c88f 100644 --- a/ios/App/PenguinWidget/en.lproj/Intents.intentdefinition +++ b/ios/App/PenguinWidget/en.lproj/Intents.intentdefinition @@ -8,62 +8,146 @@ INEnumDisplayName Servers INEnumDisplayNameID - 6u7NWg + 52E7Hb INEnumGeneratesHeader INEnumName - Server + Servers INEnumType Regular INEnumValues INEnumValueDisplayName - 未知 + 未选定 INEnumValueDisplayNameID - Tjrhvh + XOt22U INEnumValueName unknown INEnumValueDisplayName - 国服 + CN INEnumValueDisplayNameID - oIKWT9 + 9d0RSG INEnumValueIndex 1 INEnumValueName - CN + cn + INEnumValueSynonyms + + + INEnumValueSynonymSynonym + 官服 + INEnumValueSynonymSynonymID + wz6Ksv + + + INEnumValueSynonymSynonym + B服 + INEnumValueSynonymSynonymID + nX6Phw + + + INEnumValueSynonymSynonym + 中国服务器 + INEnumValueSynonymSynonymID + TDXoqS + + + INEnumValueSynonymSynonym + China Mainland + INEnumValueSynonymSynonymID + bAzUxC + + + INEnumValueSynonymSynonym + PRC + INEnumValueSynonymSynonymID + dtIn76 + + INEnumValueDisplayName - 美服 + US INEnumValueDisplayNameID - yVJ0lK + lWYm9I INEnumValueIndex 2 INEnumValueName - US + us + INEnumValueSynonyms + + + INEnumValueSynonymSynonym + 美国服务器 + INEnumValueSynonymSynonymID + 3oZzZR + + + INEnumValueSynonymSynonym + United States + INEnumValueSynonymSynonymID + ucZOUF + + + INEnumValueSynonymSynonym + USA + INEnumValueSynonymSynonymID + X0MOCd + + INEnumValueDisplayName - 日服 + JP INEnumValueDisplayNameID - tK60Y2 + 4a3hjt INEnumValueIndex 3 INEnumValueName - JP + jp + INEnumValueSynonyms + + + INEnumValueSynonymSynonym + 日本服务器 + INEnumValueSynonymSynonymID + Room6v + + + INEnumValueSynonymSynonym + Japan + INEnumValueSynonymSynonymID + NRPXVk + + INEnumValueDisplayName - 韩服 + KR INEnumValueDisplayNameID - pVCtB6 + rcOAZO INEnumValueIndex 4 INEnumValueName - KR + kr + INEnumValueSynonyms + + + INEnumValueSynonymSynonym + 韩国服务器 + INEnumValueSynonymSynonymID + d2cdqi + + + INEnumValueSynonymSynonym + Korea + INEnumValueSynonymSynonymID + GXoUkl + + @@ -71,9 +155,9 @@ INIntentDefinitionModelVersion 1.2 INIntentDefinitionNamespace - GnqMq9 + plOCob INIntentDefinitionSystemVersion - 20B29 + 20C69 INIntentDefinitionToolsBuildVersion 12C33 INIntentDefinitionToolsVersion @@ -83,12 +167,10 @@ INIntentCategory information - INIntentConfigurable - INIntentDescription - 查看最近上传数据概览 + View the Statistics Overview INIntentDescriptionID - 4h1GsM + rSZt9G INIntentEligibleForWidgets INIntentIneligibleForSuggestions @@ -96,21 +178,7 @@ INIntentInput server INIntentLastParameterTag - 6 - INIntentManagedParameterCombinations - - server - - INIntentParameterCombinationSupportsBackgroundExecution - - INIntentParameterCombinationTitle - 查看${server}的最近上传数据概览 - INIntentParameterCombinationTitleID - wqvlmq - INIntentParameterCombinationUpdatesLinked - - - + 2 INIntentName SelectServer INIntentParameters @@ -118,22 +186,20 @@ INIntentParameterConfigurable - INIntentParameterCustomDisambiguation - INIntentParameterDisplayName - 服务器 + Server INIntentParameterDisplayNameID - 9aEMGV + 438Dca INIntentParameterDisplayPriority 1 INIntentParameterEnumType - Server + Servers INIntentParameterEnumTypeNamespace - GnqMq9 + plOCob INIntentParameterMetadata INIntentParameterMetadataDefaultValue - CN + cn INIntentParameterName server @@ -155,9 +221,9 @@ INIntentParameterPromptDialogCustom INIntentParameterPromptDialogFormatString - There are ${count} options matching ‘${server}’. + Other ${count} also looks like ‘${server}’ INIntentParameterPromptDialogFormatStringID - FVUScD + KwfSyY INIntentParameterPromptDialogType DisambiguationIntroduction @@ -165,17 +231,35 @@ INIntentParameterPromptDialogCustom INIntentParameterPromptDialogFormatString - Just to confirm, you wanted ‘${server}’? + Which one do you mean? INIntentParameterPromptDialogFormatStringID - ZmbtPn + zgN72s + INIntentParameterPromptDialogType + DisambiguationSelection + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogFormatString + and + INIntentParameterPromptDialogFormatStringID + uDltiy + INIntentParameterPromptDialogType + SubsequentIntroduction + + + INIntentParameterPromptDialogCustom + + INIntentParameterPromptDialogFormatString + 请确认你要查询的是 ‘${server}’? + INIntentParameterPromptDialogFormatStringID + M0nUbM INIntentParameterPromptDialogType Confirmation - INIntentParameterSupportsResolution - INIntentParameterTag - 6 + 2 INIntentParameterType Integer @@ -197,9 +281,9 @@ INIntentTitle - 数据概览 + Statistics Overview INIntentTitleID - VzpXpK + vD918a INIntentType Custom INIntentVerb diff --git a/ios/App/PenguinWidget/en.lproj/Localizable.strings b/ios/App/PenguinWidget/en.lproj/Localizable.strings index 62eaa65a..c42fe215 100644 --- a/ios/App/PenguinWidget/en.lproj/Localizable.strings +++ b/ios/App/PenguinWidget/en.lproj/Localizable.strings @@ -9,7 +9,7 @@ "SiteStatsWidgetName" = "Statistics Overview"; "SiteStatsWidgetDesc" = "Keep track of the overview of site statistics"; "SiteStatsWidgetTitle" = "Top Report Stage (24h)"; -"WidgetViewMore" = "View More"; +"WidgetViewMore" = "More"; "ServerNameCN" = "CN"; "ServerNameUS" = "US"; diff --git a/ios/App/PenguinWidget/zh-Hans.lproj/Intents.strings b/ios/App/PenguinWidget/zh-Hans.lproj/Intents.strings new file mode 100644 index 00000000..54d8209b --- /dev/null +++ b/ios/App/PenguinWidget/zh-Hans.lproj/Intents.strings @@ -0,0 +1,42 @@ +"438Dca" = "服务器"; + +"4a3hjt" = "日服"; + +"52E7Hb" = "服务器"; + +"9d0RSG" = "国服"; + +"KwfSyY-4a3hjt" = "有其他${count}个选项与 ‘日服’ 匹配相近"; + +"KwfSyY-9d0RSG" = "有其他${count}个选项与 ‘国服’ 匹配相近"; + +"KwfSyY-XOt22U" = "有其他${count}个选项与 ‘未选定’ 匹配相近"; + +"KwfSyY-lWYm9I" = "有其他${count}个选项与 ‘美服’ 匹配相近"; + +"KwfSyY-rcOAZO" = "有其他${count}个选项与 ‘韩服’ 匹配相近"; + +"M0nUbM-4a3hjt" = "请确认你要查询的是 ‘日服’?"; + +"M0nUbM-9d0RSG" = "请确认你要查询的是 ‘国服’?"; + +"M0nUbM-XOt22U" = "请确认你要查询的是 ‘未选定’?"; + +"M0nUbM-lWYm9I" = "请确认你要查询的是 ‘美服’?"; + +"M0nUbM-rcOAZO" = "请确认你要查询的是 ‘韩服’?"; + +"XOt22U" = "未选定"; + +"lWYm9I" = "美服"; + +"rSZt9G" = "查看数据概览"; + +"rcOAZO" = "韩服"; + +"uDltiy" = "还有"; + +"vD918a" = "数据概览"; + +"zgN72s" = "请问是哪一个?"; + diff --git a/ios/App/Settings.bundle/Root.plist b/ios/App/Settings.bundle/Root.plist index cae6c241..914fd32a 100644 --- a/ios/App/Settings.bundle/Root.plist +++ b/ios/App/Settings.bundle/Root.plist @@ -16,7 +16,7 @@ DefaultValue - 3.4.1 (3) + 3.4.2 (3) Key version Title diff --git a/ios/App/genstrings.swift b/ios/App/genstrings.swift new file mode 100644 index 00000000..7384c2a6 --- /dev/null +++ b/ios/App/genstrings.swift @@ -0,0 +1,145 @@ +#!/usr/bin/swift + +import Foundation + +class GenStrings { + + var str = "Hello, playground" + let fileManager = FileManager.default + let acceptedFileExtensions = ["swift"] + let excludedFolderNames = ["Carthage", "public"] + let excludedFileNames = ["genstrings.swift"] + var regularExpresions = [String:NSRegularExpression]() + + let localizedRegex = "(?<=\")([^\"]*)(?=\".(localized|localizedFormat))|(?<=(Localized|NSLocalizedString)\\(\")([^\"]*?)(?=\")" + let commentedRegex = "(?<=.commented\\(\")([^\"]*)(?=\")" + + enum GenstringsError: Error { + case Error + } + + // Performs the genstrings functionality + func perform(path: String? = nil) { + let directoryPath = path ?? fileManager.currentDirectoryPath + let rootPath = URL(fileURLWithPath:directoryPath) + let allFiles = fetchFilesInFolder(rootPath: rootPath) + // We use a set to avoid duplicates + var localizableStrings = Set() + var comments = [String:String]() + for filePath in allFiles { + let (stringsInFile, commentsInFile) = localizableStringsInFile(filePath: filePath) + localizableStrings = localizableStrings.union(stringsInFile) + comments = comments.merging(commentsInFile, uniquingKeysWith: { (_, last) in last }) + } + // We sort the strings + let sortedStrings = localizableStrings.sorted(by: { $0 < $1 }) + var processedStrings = String() + for string in sortedStrings { + if let comment = comments[string] { + processedStrings.append("/* \(comment) */ \n") + } + processedStrings.append("\"\(string)\" = \"\(string)\"; \n") + } + print(processedStrings) + } + + // Applies regex to a file at filePath. + func localizableStringsInFile(filePath: URL) -> (Set, [String:String]) { + do { + let fileContentsData = try Data(contentsOf: filePath) + guard let fileContentsString = NSString(data: fileContentsData, encoding: String.Encoding.utf8.rawValue) else { + return (Set(), [String:String]()) + } + + let localizedMatches = try regexMatches(pattern: localizedRegex, string: fileContentsString as String) + let commentedMatches = try regexMatches(pattern: commentedRegex, string: fileContentsString as String) + + let localizedStringsArray = localizedMatches.map({fileContentsString.substring(with: $0.range)}) + var comments = [String:String]() + for m in commentedMatches { + let comment = fileContentsString.substring(with: m.range) + let localizedRange = localizedMatches.filter { $0.range.location + $0.range.length <= m.range.location }.last?.range + if localizedRange != nil { + let localized = fileContentsString.substring(with: localizedRange!) + comments[localized] = comment + } + } + + return (Set(localizedStringsArray), comments) + } catch {} + return (Set(), [String:String]()) + } + + //MARK: Regex + + func regexWithPattern(pattern: String) throws -> NSRegularExpression { + var safeRegex = regularExpresions + if let regex = safeRegex[pattern] { + return regex + } + else { + do { + let currentPattern: NSRegularExpression + currentPattern = try NSRegularExpression(pattern: pattern, options:NSRegularExpression.Options.caseInsensitive) + safeRegex.updateValue(currentPattern, forKey: pattern) + regularExpresions = safeRegex + return currentPattern + } + catch { + throw GenstringsError.Error + } + } + } + + func regexMatches(pattern: String, string: String) throws -> [NSTextCheckingResult] { + do { + let internalString = string + let currentPattern = try regexWithPattern(pattern: pattern) + // NSRegularExpression accepts Swift strings but works with NSString under the hood. Safer to bridge to NSString for taking range. + let nsString = internalString as NSString + let stringRange = NSMakeRange(0, nsString.length) + let matches = currentPattern.matches(in: internalString, options: [], range: stringRange) + return matches + } + catch { + throw GenstringsError.Error + } + } + + //MARK: File manager + + func fetchFilesInFolder(rootPath: URL) -> [URL] { + var files = [URL]() + do { + let directoryContents = try fileManager.contentsOfDirectory(at: rootPath as URL, includingPropertiesForKeys: [], options: .skipsHiddenFiles) + for urlPath in directoryContents { + let stringPath = urlPath.path + let lastPathComponent = urlPath.lastPathComponent + let pathExtension = urlPath.pathExtension + var isDir : ObjCBool = false + if fileManager.fileExists(atPath: stringPath, isDirectory:&isDir) { + if isDir.boolValue { + if !excludedFolderNames.contains(lastPathComponent) { + let dirFiles = fetchFilesInFolder(rootPath: urlPath) + files.append(contentsOf: dirFiles) + } + } else { + if acceptedFileExtensions.contains(pathExtension) && !excludedFileNames.contains(lastPathComponent) { + files.append(urlPath) + } + } + } + } + } catch {} + return files + } + +} + +let genStrings = GenStrings() +if CommandLine.arguments.count > 1 { + let path = CommandLine.arguments[1] + genStrings.perform(path: path) +} else { + genStrings.perform() +} diff --git a/package.json b/package.json index 637a6196..c091cc59 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "penguin-stats-frontend", - "version": "3.4.2", + "version": "3.5.0", "private": true, "author": "Penguin Statistics Contributors (https://github.com/orgs/penguin-statistics/people)", "scripts": { @@ -42,6 +42,7 @@ "highcharts-vue": "^1.3.5", "intl-collator": "^0.1.6", "js-cookie": "^2.2.1", + "jszip": "^3.6.0", "katex": "^0.12.0", "lodash": "^4.17.20", "marked": "^1.0.0", @@ -69,13 +70,19 @@ "@vue/cli-plugin-babel": "~4.4.6", "@vue/cli-plugin-eslint": "~4.4.6", "@vue/cli-service": "^4.4.6", + "@vue/eslint-config-standard": "5.1.2", "axios": "^0.19.0", "babel-eslint": "^10.1.0", "babel-loader": "^8.2.1", "browserslist-ga-export": "^2.0.0", + "copy-webpack-plugin": "^6.2.1", "cross-env": "^7.0.3", "cz-conventional-changelog": "3.0.2", "eslint": "^6.7.2", + "eslint-plugin-import": "^2.20.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^4.3.1", + "eslint-plugin-standard": "^5.0.0", "eslint-plugin-vue": "^6.2.2", "eslint-plugin-vuetify": "^1.0.0-beta.5", "husky": "^4.2.5", @@ -89,6 +96,7 @@ "vue-cli-plugin-vuetify": "^2.0.5", "vue-template-compiler": "^2.6.10", "vuetify-loader": "^1.4.3", + "webfontloader": "^1.6.28", "webpack": "^4.42.1", "webpack-bundle-analyzer": "^3.8.0", "webpack-cli": "^3.3.12", diff --git a/public/index.html b/public/index.html deleted file mode 100644 index d5c8cd28..00000000 --- a/public/index.html +++ /dev/null @@ -1,97 +0,0 @@ - - - - - - <% if (PENGUIN_PLATFORM === 'app') { %> - - - <% } else { %> - - <% } %> - - - - 企鹅物流数据统计 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
- -
-
-
-
-
-
-
-
-
- 正在加载 -
- 首次加载可能较慢,请耐心等待 -
-
- - 检测到页面资源异常,请尝试更新到最新版本 - -
- -
- -
-
- - - - - - - diff --git a/public/items.zip b/public/items.zip new file mode 100644 index 00000000..31632b18 Binary files /dev/null and b/public/items.zip differ diff --git a/public/penguin.js b/public/penguin.js new file mode 100644 index 00000000..ba40ddfd --- /dev/null +++ b/public/penguin.js @@ -0,0 +1 @@ +var Module=typeof Module!=="undefined"?Module:{};var moduleOverrides={};var key;for(key in Module){if(Module.hasOwnProperty(key)){moduleOverrides[key]=Module[key]}}var arguments_=[];var thisProgram="./this.program";var quit_=function(status,toThrow){throw toThrow};var ENVIRONMENT_IS_WEB=false;var ENVIRONMENT_IS_WORKER=false;var ENVIRONMENT_IS_NODE=false;var ENVIRONMENT_HAS_NODE=false;var ENVIRONMENT_IS_SHELL=false;ENVIRONMENT_IS_WEB=typeof window==="object";ENVIRONMENT_IS_WORKER=typeof importScripts==="function";ENVIRONMENT_HAS_NODE=typeof process==="object"&&typeof process.versions==="object"&&typeof process.versions.node==="string";ENVIRONMENT_IS_NODE=ENVIRONMENT_HAS_NODE&&!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_WORKER;ENVIRONMENT_IS_SHELL=!ENVIRONMENT_IS_WEB&&!ENVIRONMENT_IS_NODE&&!ENVIRONMENT_IS_WORKER;var scriptDirectory="";function locateFile(path){if(Module["locateFile"]){return Module["locateFile"](path,scriptDirectory)}return scriptDirectory+path}var read_,readAsync,readBinary,setWindowTitle;if(ENVIRONMENT_IS_NODE){scriptDirectory=__dirname+"/";var nodeFS;var nodePath;read_=function shell_read(filename,binary){var ret;if(!nodeFS)nodeFS=require("fs");if(!nodePath)nodePath=require("path");filename=nodePath["normalize"](filename);ret=nodeFS["readFileSync"](filename);return binary?ret:ret.toString()};readBinary=function readBinary(filename){var ret=read_(filename,true);if(!ret.buffer){ret=new Uint8Array(ret)}assert(ret.buffer);return ret};if(process["argv"].length>1){thisProgram=process["argv"][1].replace(/\\/g,"/")}arguments_=process["argv"].slice(2);if(typeof module!=="undefined"){module["exports"]=Module}process["on"]("uncaughtException",function(ex){if(!(ex instanceof ExitStatus)){throw ex}});process["on"]("unhandledRejection",abort);quit_=function(status){process["exit"](status)};Module["inspect"]=function(){return"[Emscripten Module object]"}}else if(ENVIRONMENT_IS_SHELL){if(typeof read!="undefined"){read_=function shell_read(f){return read(f)}}readBinary=function readBinary(f){var data;if(typeof readbuffer==="function"){return new Uint8Array(readbuffer(f))}data=read(f,"binary");assert(typeof data==="object");return data};if(typeof scriptArgs!="undefined"){arguments_=scriptArgs}else if(typeof arguments!="undefined"){arguments_=arguments}if(typeof quit==="function"){quit_=function(status){quit(status)}}if(typeof print!=="undefined"){if(typeof console==="undefined")console={};console.log=print;console.warn=console.error=typeof printErr!=="undefined"?printErr:print}}else if(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER){if(ENVIRONMENT_IS_WORKER){scriptDirectory=self.location.href}else if(document.currentScript){scriptDirectory=document.currentScript.src}if(scriptDirectory.indexOf("blob:")!==0){scriptDirectory=scriptDirectory.substr(0,scriptDirectory.lastIndexOf("/")+1)}else{scriptDirectory=""}read_=function shell_read(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.send(null);return xhr.responseText};if(ENVIRONMENT_IS_WORKER){readBinary=function readBinary(url){var xhr=new XMLHttpRequest;xhr.open("GET",url,false);xhr.responseType="arraybuffer";xhr.send(null);return new Uint8Array(xhr.response)}}readAsync=function readAsync(url,onload,onerror){var xhr=new XMLHttpRequest;xhr.open("GET",url,true);xhr.responseType="arraybuffer";xhr.onload=function xhr_onload(){if(xhr.status==200||xhr.status==0&&xhr.response){onload(xhr.response);return}onerror()};xhr.onerror=onerror;xhr.send(null)};setWindowTitle=function(title){document.title=title}}else{}var out=Module["print"]||console.log.bind(console);var err=Module["printErr"]||console.warn.bind(console);for(key in moduleOverrides){if(moduleOverrides.hasOwnProperty(key)){Module[key]=moduleOverrides[key]}}moduleOverrides=null;if(Module["arguments"])arguments_=Module["arguments"];if(Module["thisProgram"])thisProgram=Module["thisProgram"];if(Module["quit"])quit_=Module["quit"];function dynamicAlloc(size){var ret=HEAP32[DYNAMICTOP_PTR>>2];var end=ret+size+15&-16;if(end>_emscripten_get_heap_size()){abort()}HEAP32[DYNAMICTOP_PTR>>2]=end;return ret}function getNativeTypeSize(type){switch(type){case"i1":case"i8":return 1;case"i16":return 2;case"i32":return 4;case"i64":return 8;case"float":return 4;case"double":return 8;default:{if(type[type.length-1]==="*"){return 4}else if(type[0]==="i"){var bits=parseInt(type.substr(1));assert(bits%8===0,"getNativeTypeSize invalid bits "+bits+", type "+type);return bits/8}else{return 0}}}}var tempRet0=0;var setTempRet0=function(value){tempRet0=value};var getTempRet0=function(){return tempRet0};var wasmBinary;if(Module["wasmBinary"])wasmBinary=Module["wasmBinary"];var noExitRuntime;if(Module["noExitRuntime"])noExitRuntime=Module["noExitRuntime"];if(typeof WebAssembly!=="object"){err("no native wasm support detected")}function setValue(ptr,value,type,noSafe){type=type||"i8";if(type.charAt(type.length-1)==="*")type="i32";switch(type){case"i1":HEAP8[ptr>>0]=value;break;case"i8":HEAP8[ptr>>0]=value;break;case"i16":HEAP16[ptr>>1]=value;break;case"i32":HEAP32[ptr>>2]=value;break;case"i64":tempI64=[value>>>0,(tempDouble=value,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[ptr>>2]=tempI64[0],HEAP32[ptr+4>>2]=tempI64[1];break;case"float":HEAPF32[ptr>>2]=value;break;case"double":HEAPF64[ptr>>3]=value;break;default:abort("invalid type for setValue: "+type)}}var wasmMemory;var wasmTable=new WebAssembly.Table({"initial":2627,"maximum":2627+0,"element":"anyfunc"});var ABORT=false;var EXITSTATUS=0;function assert(condition,text){if(!condition){abort("Assertion failed: "+text)}}function getCFunc(ident){var func=Module["_"+ident];assert(func,"Cannot call unknown function "+ident+", make sure it is exported");return func}function ccall(ident,returnType,argTypes,args,opts){var toC={"string":function(str){var ret=0;if(str!==null&&str!==undefined&&str!==0){var len=(str.length<<2)+1;ret=stackAlloc(len);stringToUTF8(str,ret,len)}return ret},"array":function(arr){var ret=stackAlloc(arr.length);writeArrayToMemory(arr,ret);return ret}};function convertReturnValue(ret){if(returnType==="string")return UTF8ToString(ret);if(returnType==="boolean")return Boolean(ret);return ret}var func=getCFunc(ident);var cArgs=[];var stack=0;if(args){for(var i=0;i>2]=0}stop=ret+size;while(ptr>0]=0}return ret}if(singleType==="i8"){if(slab.subarray||slab.slice){HEAPU8.set(slab,ret)}else{HEAPU8.set(new Uint8Array(slab),ret)}return ret}var i=0,type,typeSize,previousType;while(i=endIdx))++endPtr;if(endPtr-idx>16&&u8Array.subarray&&UTF8Decoder){return UTF8Decoder.decode(u8Array.subarray(idx,endPtr))}else{var str="";while(idx>10,56320|ch&1023)}}}return str}function UTF8ToString(ptr,maxBytesToRead){return ptr?UTF8ArrayToString(HEAPU8,ptr,maxBytesToRead):""}function stringToUTF8Array(str,outU8Array,outIdx,maxBytesToWrite){if(!(maxBytesToWrite>0))return 0;var startIdx=outIdx;var endIdx=outIdx+maxBytesToWrite-1;for(var i=0;i=55296&&u<=57343){var u1=str.charCodeAt(++i);u=65536+((u&1023)<<10)|u1&1023}if(u<=127){if(outIdx>=endIdx)break;outU8Array[outIdx++]=u}else if(u<=2047){if(outIdx+1>=endIdx)break;outU8Array[outIdx++]=192|u>>6;outU8Array[outIdx++]=128|u&63}else if(u<=65535){if(outIdx+2>=endIdx)break;outU8Array[outIdx++]=224|u>>12;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}else{if(outIdx+3>=endIdx)break;outU8Array[outIdx++]=240|u>>18;outU8Array[outIdx++]=128|u>>12&63;outU8Array[outIdx++]=128|u>>6&63;outU8Array[outIdx++]=128|u&63}}outU8Array[outIdx]=0;return outIdx-startIdx}function stringToUTF8(str,outPtr,maxBytesToWrite){return stringToUTF8Array(str,HEAPU8,outPtr,maxBytesToWrite)}function lengthBytesUTF8(str){var len=0;for(var i=0;i=55296&&u<=57343)u=65536+((u&1023)<<10)|str.charCodeAt(++i)&1023;if(u<=127)++len;else if(u<=2047)len+=2;else if(u<=65535)len+=3;else len+=4}return len}var UTF16Decoder=typeof TextDecoder!=="undefined"?new TextDecoder("utf-16le"):undefined;function writeArrayToMemory(array,buffer){HEAP8.set(array,buffer)}function writeAsciiToMemory(str,buffer,dontAddNull){for(var i=0;i>0]=str.charCodeAt(i)}if(!dontAddNull)HEAP8[buffer>>0]=0}var PAGE_SIZE=16384;var WASM_PAGE_SIZE=65536;function alignUp(x,multiple){if(x%multiple>0){x+=multiple-x%multiple}return x}var buffer,HEAP8,HEAPU8,HEAP16,HEAPU16,HEAP32,HEAPU32,HEAPF32,HEAPF64;function updateGlobalBufferAndViews(buf){buffer=buf;Module["HEAP8"]=HEAP8=new Int8Array(buf);Module["HEAP16"]=HEAP16=new Int16Array(buf);Module["HEAP32"]=HEAP32=new Int32Array(buf);Module["HEAPU8"]=HEAPU8=new Uint8Array(buf);Module["HEAPU16"]=HEAPU16=new Uint16Array(buf);Module["HEAPU32"]=HEAPU32=new Uint32Array(buf);Module["HEAPF32"]=HEAPF32=new Float32Array(buf);Module["HEAPF64"]=HEAPF64=new Float64Array(buf)}var DYNAMIC_BASE=5673104,DYNAMICTOP_PTR=430064;var INITIAL_TOTAL_MEMORY=Module["TOTAL_MEMORY"]||16777216;if(Module["wasmMemory"]){wasmMemory=Module["wasmMemory"]}else{wasmMemory=new WebAssembly.Memory({"initial":INITIAL_TOTAL_MEMORY/WASM_PAGE_SIZE})}if(wasmMemory){buffer=wasmMemory.buffer}INITIAL_TOTAL_MEMORY=buffer.byteLength;updateGlobalBufferAndViews(buffer);HEAP32[DYNAMICTOP_PTR>>2]=DYNAMIC_BASE;function callRuntimeCallbacks(callbacks){while(callbacks.length>0){var callback=callbacks.shift();if(typeof callback=="function"){callback();continue}var func=callback.func;if(typeof func==="number"){if(callback.arg===undefined){Module["dynCall_v"](func)}else{Module["dynCall_vi"](func,callback.arg)}}else{func(callback.arg===undefined?null:callback.arg)}}}var __ATPRERUN__=[];var __ATINIT__=[];var __ATMAIN__=[];var __ATPOSTRUN__=[];var runtimeInitialized=false;var runtimeExited=false;function preRun(){if(Module["preRun"]){if(typeof Module["preRun"]=="function")Module["preRun"]=[Module["preRun"]];while(Module["preRun"].length){addOnPreRun(Module["preRun"].shift())}}callRuntimeCallbacks(__ATPRERUN__)}function initRuntime(){runtimeInitialized=true;if(!Module["noFSInit"]&&!FS.init.initialized)FS.init();TTY.init();callRuntimeCallbacks(__ATINIT__)}function preMain(){FS.ignorePermissions=false;callRuntimeCallbacks(__ATMAIN__)}function exitRuntime(){runtimeExited=true}function postRun(){if(Module["postRun"]){if(typeof Module["postRun"]=="function")Module["postRun"]=[Module["postRun"]];while(Module["postRun"].length){addOnPostRun(Module["postRun"].shift())}}callRuntimeCallbacks(__ATPOSTRUN__)}function addOnPreRun(cb){__ATPRERUN__.unshift(cb)}function addOnPostRun(cb){__ATPOSTRUN__.unshift(cb)}var Math_abs=Math.abs;var Math_ceil=Math.ceil;var Math_floor=Math.floor;var Math_min=Math.min;var runDependencies=0;var runDependencyWatcher=null;var dependenciesFulfilled=null;function getUniqueRunDependency(id){return id}function addRunDependency(id){runDependencies++;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}}function removeRunDependency(id){runDependencies--;if(Module["monitorRunDependencies"]){Module["monitorRunDependencies"](runDependencies)}if(runDependencies==0){if(runDependencyWatcher!==null){clearInterval(runDependencyWatcher);runDependencyWatcher=null}if(dependenciesFulfilled){var callback=dependenciesFulfilled;dependenciesFulfilled=null;callback()}}}Module["preloadedImages"]={};Module["preloadedAudios"]={};function abort(what){if(Module["onAbort"]){Module["onAbort"](what)}what+="";out(what);err(what);ABORT=true;EXITSTATUS=1;throw"abort("+what+"). Build with -s ASSERTIONS=1 for more info."}var dataURIPrefix="data:application/octet-stream;base64,";function isDataURI(filename){return String.prototype.startsWith?filename.startsWith(dataURIPrefix):filename.indexOf(dataURIPrefix)===0}var wasmBinaryFile="penguin.wasm";if(!isDataURI(wasmBinaryFile)){wasmBinaryFile=locateFile(wasmBinaryFile)}function getBinary(){try{if(wasmBinary){return new Uint8Array(wasmBinary)}if(readBinary){return readBinary(wasmBinaryFile)}else{throw"both async and sync fetching of the wasm failed"}}catch(err){abort(err)}}function getBinaryPromise(){if(!wasmBinary&&(ENVIRONMENT_IS_WEB||ENVIRONMENT_IS_WORKER)&&typeof fetch==="function"){return fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){if(!response["ok"]){throw"failed to load wasm binary file at '"+wasmBinaryFile+"'"}return response["arrayBuffer"]()}).catch(function(){return getBinary()})}return new Promise(function(resolve,reject){resolve(getBinary())})}function createWasm(){var info={"env":asmLibraryArg,"wasi_unstable":asmLibraryArg};function receiveInstance(instance,module){var exports=instance.exports;Module["asm"]=exports;removeRunDependency("wasm-instantiate")}addRunDependency("wasm-instantiate");function receiveInstantiatedSource(output){receiveInstance(output["instance"])}function instantiateArrayBuffer(receiver){return getBinaryPromise().then(function(binary){return WebAssembly.instantiate(binary,info)}).then(receiver,function(reason){err("failed to asynchronously prepare wasm: "+reason);abort(reason)})}function instantiateAsync(){if(!wasmBinary&&typeof WebAssembly.instantiateStreaming==="function"&&!isDataURI(wasmBinaryFile)&&typeof fetch==="function"){fetch(wasmBinaryFile,{credentials:"same-origin"}).then(function(response){var result=WebAssembly.instantiateStreaming(response,info);return result.then(receiveInstantiatedSource,function(reason){err("wasm streaming compile failed: "+reason);err("falling back to ArrayBuffer instantiation");instantiateArrayBuffer(receiveInstantiatedSource)})})}else{return instantiateArrayBuffer(receiveInstantiatedSource)}}if(Module["instantiateWasm"]){try{var exports=Module["instantiateWasm"](info,receiveInstance);return exports}catch(e){err("Module.instantiateWasm callback failed with error: "+e);return false}}instantiateAsync();return{}}var tempDouble;var tempI64;__ATINIT__.push({func:function(){___wasm_call_ctors()}});function demangle(func){return func}function demangleAll(text){var regex=/\b_Z[\w\d_]+/g;return text.replace(regex,function(x){var y=demangle(x);return x===y?x:y+" ["+x+"]"})}function jsStackTrace(){var err=new Error;if(!err.stack){try{throw new Error(0)}catch(e){err=e}if(!err.stack){return"(no stack trace available)"}}return err.stack.toString()}function stackTrace(){var js=jsStackTrace();if(Module["extraStackTrace"])js+="\n"+Module["extraStackTrace"]();return demangleAll(js)}function _emscripten_get_now(){abort()}function _emscripten_get_now_is_monotonic(){return 0||ENVIRONMENT_IS_NODE||typeof dateNow!=="undefined"||typeof performance==="object"&&performance&&typeof performance["now"]==="function"}function ___setErrNo(value){if(Module["___errno_location"])HEAP32[Module["___errno_location"]()>>2]=value;return value}function _clock_gettime(clk_id,tp){var now;if(clk_id===0){now=Date.now()}else if(clk_id===1&&_emscripten_get_now_is_monotonic()){now=_emscripten_get_now()}else{___setErrNo(28);return-1}HEAP32[tp>>2]=now/1e3|0;HEAP32[tp+4>>2]=now%1e3*1e3*1e3|0;return 0}function ___clock_gettime(a0,a1){return _clock_gettime(a0,a1)}function ___cxa_allocate_exception(size){return _malloc(size)}var ___exception_infos={};var ___exception_last=0;function ___cxa_throw(ptr,type,destructor){___exception_infos[ptr]={ptr:ptr,adjusted:[ptr],type:type,destructor:destructor,refcount:0,caught:false,rethrown:false};___exception_last=ptr;if(!("uncaught_exception"in __ZSt18uncaught_exceptionv)){__ZSt18uncaught_exceptionv.uncaught_exceptions=1}else{__ZSt18uncaught_exceptionv.uncaught_exceptions++}throw ptr}function ___lock(){}function ___map_file(pathname,size){___setErrNo(63);return-1}var PATH={splitPath:function(filename){var splitPathRe=/^(\/?|)([\s\S]*?)((?:\.{1,2}|[^\/]+?|)(\.[^.\/]*|))(?:[\/]*)$/;return splitPathRe.exec(filename).slice(1)},normalizeArray:function(parts,allowAboveRoot){var up=0;for(var i=parts.length-1;i>=0;i--){var last=parts[i];if(last==="."){parts.splice(i,1)}else if(last===".."){parts.splice(i,1);up++}else if(up){parts.splice(i,1);up--}}if(allowAboveRoot){for(;up;up--){parts.unshift("..")}}return parts},normalize:function(path){var isAbsolute=path.charAt(0)==="/",trailingSlash=path.substr(-1)==="/";path=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),!isAbsolute).join("/");if(!path&&!isAbsolute){path="."}if(path&&trailingSlash){path+="/"}return(isAbsolute?"/":"")+path},dirname:function(path){var result=PATH.splitPath(path),root=result[0],dir=result[1];if(!root&&!dir){return"."}if(dir){dir=dir.substr(0,dir.length-1)}return root+dir},basename:function(path){if(path==="/")return"/";var lastSlash=path.lastIndexOf("/");if(lastSlash===-1)return path;return path.substr(lastSlash+1)},extname:function(path){return PATH.splitPath(path)[3]},join:function(){var paths=Array.prototype.slice.call(arguments,0);return PATH.normalize(paths.join("/"))},join2:function(l,r){return PATH.normalize(l+"/"+r)}};var PATH_FS={resolve:function(){var resolvedPath="",resolvedAbsolute=false;for(var i=arguments.length-1;i>=-1&&!resolvedAbsolute;i--){var path=i>=0?arguments[i]:FS.cwd();if(typeof path!=="string"){throw new TypeError("Arguments to path.resolve must be strings")}else if(!path){return""}resolvedPath=path+"/"+resolvedPath;resolvedAbsolute=path.charAt(0)==="/"}resolvedPath=PATH.normalizeArray(resolvedPath.split("/").filter(function(p){return!!p}),!resolvedAbsolute).join("/");return(resolvedAbsolute?"/":"")+resolvedPath||"."},relative:function(from,to){from=PATH_FS.resolve(from).substr(1);to=PATH_FS.resolve(to).substr(1);function trim(arr){var start=0;for(;start=0;end--){if(arr[end]!=="")break}if(start>end)return[];return arr.slice(start,end-start+1)}var fromParts=trim(from.split("/"));var toParts=trim(to.split("/"));var length=Math.min(fromParts.length,toParts.length);var samePartsLength=length;for(var i=0;i0){result=buf.slice(0,bytesRead).toString("utf-8")}else{result=null}}else if(typeof window!="undefined"&&typeof window.prompt=="function"){result=window.prompt("Input: ");if(result!==null){result+="\n"}}else if(typeof readline=="function"){result=readline();if(result!==null){result+="\n"}}if(!result){return null}tty.input=intArrayFromString(result,true)}return tty.input.shift()},put_char:function(tty,val){if(val===null||val===10){out(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){out(UTF8ArrayToString(tty.output,0));tty.output=[]}}},default_tty1_ops:{put_char:function(tty,val){if(val===null||val===10){err(UTF8ArrayToString(tty.output,0));tty.output=[]}else{if(val!=0)tty.output.push(val)}},flush:function(tty){if(tty.output&&tty.output.length>0){err(UTF8ArrayToString(tty.output,0));tty.output=[]}}}};var MEMFS={ops_table:null,mount:function(mount){return MEMFS.createNode(null,"/",16384|511,0)},createNode:function(parent,name,mode,dev){if(FS.isBlkdev(mode)||FS.isFIFO(mode)){throw new FS.ErrnoError(63)}if(!MEMFS.ops_table){MEMFS.ops_table={dir:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,lookup:MEMFS.node_ops.lookup,mknod:MEMFS.node_ops.mknod,rename:MEMFS.node_ops.rename,unlink:MEMFS.node_ops.unlink,rmdir:MEMFS.node_ops.rmdir,readdir:MEMFS.node_ops.readdir,symlink:MEMFS.node_ops.symlink},stream:{llseek:MEMFS.stream_ops.llseek}},file:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:{llseek:MEMFS.stream_ops.llseek,read:MEMFS.stream_ops.read,write:MEMFS.stream_ops.write,allocate:MEMFS.stream_ops.allocate,mmap:MEMFS.stream_ops.mmap,msync:MEMFS.stream_ops.msync}},link:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr,readlink:MEMFS.node_ops.readlink},stream:{}},chrdev:{node:{getattr:MEMFS.node_ops.getattr,setattr:MEMFS.node_ops.setattr},stream:FS.chrdev_stream_ops}}}var node=FS.createNode(parent,name,mode,dev);if(FS.isDir(node.mode)){node.node_ops=MEMFS.ops_table.dir.node;node.stream_ops=MEMFS.ops_table.dir.stream;node.contents={}}else if(FS.isFile(node.mode)){node.node_ops=MEMFS.ops_table.file.node;node.stream_ops=MEMFS.ops_table.file.stream;node.usedBytes=0;node.contents=null}else if(FS.isLink(node.mode)){node.node_ops=MEMFS.ops_table.link.node;node.stream_ops=MEMFS.ops_table.link.stream}else if(FS.isChrdev(node.mode)){node.node_ops=MEMFS.ops_table.chrdev.node;node.stream_ops=MEMFS.ops_table.chrdev.stream}node.timestamp=Date.now();if(parent){parent.contents[name]=node}return node},getFileDataAsRegularArray:function(node){if(node.contents&&node.contents.subarray){var arr=[];for(var i=0;i=newCapacity)return;var CAPACITY_DOUBLING_MAX=1024*1024;newCapacity=Math.max(newCapacity,prevCapacity*(prevCapacity0)node.contents.set(oldContents.subarray(0,node.usedBytes),0);return},resizeFileStorage:function(node,newSize){if(node.usedBytes==newSize)return;if(newSize==0){node.contents=null;node.usedBytes=0;return}if(!node.contents||node.contents.subarray){var oldContents=node.contents;node.contents=new Uint8Array(new ArrayBuffer(newSize));if(oldContents){node.contents.set(oldContents.subarray(0,Math.min(newSize,node.usedBytes)))}node.usedBytes=newSize;return}if(!node.contents)node.contents=[];if(node.contents.length>newSize)node.contents.length=newSize;else while(node.contents.length=stream.node.usedBytes)return 0;var size=Math.min(stream.node.usedBytes-position,length);if(size>8&&contents.subarray){buffer.set(contents.subarray(position,position+size),offset)}else{for(var i=0;i0||position+lengthe2.timestamp){create.push(key);total++}});var remove=[];Object.keys(dst.entries).forEach(function(key){var e=dst.entries[key];var e2=src.entries[key];if(!e2){remove.push(key);total++}});if(!total){return callback(null)}var errored=false;var db=src.type==="remote"?src.db:dst.db;var transaction=db.transaction([IDBFS.DB_STORE_NAME],"readwrite");var store=transaction.objectStore(IDBFS.DB_STORE_NAME);function done(err){if(err&&!errored){errored=true;return callback(err)}}transaction.onerror=function(e){done(this.error);e.preventDefault()};transaction.oncomplete=function(e){if(!errored){callback(null)}};create.sort().forEach(function(path){if(dst.type==="local"){IDBFS.loadRemoteEntry(store,path,function(err,entry){if(err)return done(err);IDBFS.storeLocalEntry(path,entry,done)})}else{IDBFS.loadLocalEntry(path,function(err,entry){if(err)return done(err);IDBFS.storeRemoteEntry(store,path,entry,done)})}});remove.sort().reverse().forEach(function(path){if(dst.type==="local"){IDBFS.removeLocalEntry(path,done)}else{IDBFS.removeRemoteEntry(store,path,done)}})}};var ERRNO_CODES={EPERM:63,ENOENT:44,ESRCH:71,EINTR:27,EIO:29,ENXIO:60,E2BIG:1,ENOEXEC:45,EBADF:8,ECHILD:12,EAGAIN:6,EWOULDBLOCK:6,ENOMEM:48,EACCES:2,EFAULT:21,ENOTBLK:105,EBUSY:10,EEXIST:20,EXDEV:75,ENODEV:43,ENOTDIR:54,EISDIR:31,EINVAL:28,ENFILE:41,EMFILE:33,ENOTTY:59,ETXTBSY:74,EFBIG:22,ENOSPC:51,ESPIPE:70,EROFS:69,EMLINK:34,EPIPE:64,EDOM:18,ERANGE:68,ENOMSG:49,EIDRM:24,ECHRNG:106,EL2NSYNC:156,EL3HLT:107,EL3RST:108,ELNRNG:109,EUNATCH:110,ENOCSI:111,EL2HLT:112,EDEADLK:16,ENOLCK:46,EBADE:113,EBADR:114,EXFULL:115,ENOANO:104,EBADRQC:103,EBADSLT:102,EDEADLOCK:16,EBFONT:101,ENOSTR:100,ENODATA:116,ETIME:117,ENOSR:118,ENONET:119,ENOPKG:120,EREMOTE:121,ENOLINK:47,EADV:122,ESRMNT:123,ECOMM:124,EPROTO:65,EMULTIHOP:36,EDOTDOT:125,EBADMSG:9,ENOTUNIQ:126,EBADFD:127,EREMCHG:128,ELIBACC:129,ELIBBAD:130,ELIBSCN:131,ELIBMAX:132,ELIBEXEC:133,ENOSYS:52,ENOTEMPTY:55,ENAMETOOLONG:37,ELOOP:32,EOPNOTSUPP:138,EPFNOSUPPORT:139,ECONNRESET:15,ENOBUFS:42,EAFNOSUPPORT:5,EPROTOTYPE:67,ENOTSOCK:57,ENOPROTOOPT:50,ESHUTDOWN:140,ECONNREFUSED:14,EADDRINUSE:3,ECONNABORTED:13,ENETUNREACH:40,ENETDOWN:38,ETIMEDOUT:73,EHOSTDOWN:142,EHOSTUNREACH:23,EINPROGRESS:26,EALREADY:7,EDESTADDRREQ:17,EMSGSIZE:35,EPROTONOSUPPORT:66,ESOCKTNOSUPPORT:137,EADDRNOTAVAIL:4,ENETRESET:39,EISCONN:30,ENOTCONN:53,ETOOMANYREFS:141,EUSERS:136,EDQUOT:19,ESTALE:72,ENOTSUP:138,ENOMEDIUM:148,EILSEQ:25,EOVERFLOW:61,ECANCELED:11,ENOTRECOVERABLE:56,EOWNERDEAD:62,ESTRPIPE:135};var NODEFS={isWindows:false,staticInit:function(){NODEFS.isWindows=!!process.platform.match(/^win/);var flags=process["binding"]("constants");if(flags["fs"]){flags=flags["fs"]}NODEFS.flagsForNodeMap={1024:flags["O_APPEND"],64:flags["O_CREAT"],128:flags["O_EXCL"],0:flags["O_RDONLY"],2:flags["O_RDWR"],4096:flags["O_SYNC"],512:flags["O_TRUNC"],1:flags["O_WRONLY"]}},bufferFrom:function(arrayBuffer){return Buffer["alloc"]?Buffer.from(arrayBuffer):new Buffer(arrayBuffer)},convertNodeCode:function(e){var code=e.code;assert(code in ERRNO_CODES);return ERRNO_CODES[code]},mount:function(mount){assert(ENVIRONMENT_HAS_NODE);return NODEFS.createNode(null,"/",NODEFS.getMode(mount.opts.root),0)},createNode:function(parent,name,mode,dev){if(!FS.isDir(mode)&&!FS.isFile(mode)&&!FS.isLink(mode)){throw new FS.ErrnoError(28)}var node=FS.createNode(parent,name,mode);node.node_ops=NODEFS.node_ops;node.stream_ops=NODEFS.stream_ops;return node},getMode:function(path){var stat;try{stat=fs.lstatSync(path);if(NODEFS.isWindows){stat.mode=stat.mode|(stat.mode&292)>>2}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return stat.mode},realPath:function(node){var parts=[];while(node.parent!==node){parts.push(node.name);node=node.parent}parts.push(node.mount.opts.root);parts.reverse();return PATH.join.apply(null,parts)},flagsForNode:function(flags){flags&=~2097152;flags&=~2048;flags&=~32768;flags&=~524288;var newFlags=0;for(var k in NODEFS.flagsForNodeMap){if(flags&k){newFlags|=NODEFS.flagsForNodeMap[k];flags^=k}}if(!flags){return newFlags}else{throw new FS.ErrnoError(28)}},node_ops:{getattr:function(node){var path=NODEFS.realPath(node);var stat;try{stat=fs.lstatSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}if(NODEFS.isWindows&&!stat.blksize){stat.blksize=4096}if(NODEFS.isWindows&&!stat.blocks){stat.blocks=(stat.size+stat.blksize-1)/stat.blksize|0}return{dev:stat.dev,ino:stat.ino,mode:stat.mode,nlink:stat.nlink,uid:stat.uid,gid:stat.gid,rdev:stat.rdev,size:stat.size,atime:stat.atime,mtime:stat.mtime,ctime:stat.ctime,blksize:stat.blksize,blocks:stat.blocks}},setattr:function(node,attr){var path=NODEFS.realPath(node);try{if(attr.mode!==undefined){fs.chmodSync(path,attr.mode);node.mode=attr.mode}if(attr.timestamp!==undefined){var date=new Date(attr.timestamp);fs.utimesSync(path,date,date)}if(attr.size!==undefined){fs.truncateSync(path,attr.size)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},lookup:function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);var mode=NODEFS.getMode(path);return NODEFS.createNode(parent,name,mode)},mknod:function(parent,name,mode,dev){var node=NODEFS.createNode(parent,name,mode,dev);var path=NODEFS.realPath(node);try{if(FS.isDir(node.mode)){fs.mkdirSync(path,node.mode)}else{fs.writeFileSync(path,"",{mode:node.mode})}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}return node},rename:function(oldNode,newDir,newName){var oldPath=NODEFS.realPath(oldNode);var newPath=PATH.join2(NODEFS.realPath(newDir),newName);try{fs.renameSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},unlink:function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.unlinkSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},rmdir:function(parent,name){var path=PATH.join2(NODEFS.realPath(parent),name);try{fs.rmdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readdir:function(node){var path=NODEFS.realPath(node);try{return fs.readdirSync(path)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},symlink:function(parent,newName,oldPath){var newPath=PATH.join2(NODEFS.realPath(parent),newName);try{fs.symlinkSync(oldPath,newPath)}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},readlink:function(node){var path=NODEFS.realPath(node);try{path=fs.readlinkSync(path);path=NODEJS_PATH.relative(NODEJS_PATH.resolve(node.mount.opts.root),path);return path}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}},stream_ops:{open:function(stream){var path=NODEFS.realPath(stream.node);try{if(FS.isFile(stream.node.mode)){stream.nfd=fs.openSync(path,NODEFS.flagsForNode(stream.flags))}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},close:function(stream){try{if(FS.isFile(stream.node.mode)&&stream.nfd){fs.closeSync(stream.nfd)}}catch(e){if(!e.code)throw e;throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},read:function(stream,buffer,offset,length,position){if(length===0)return 0;try{return fs.readSync(stream.nfd,NODEFS.bufferFrom(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},write:function(stream,buffer,offset,length,position){try{return fs.writeSync(stream.nfd,NODEFS.bufferFrom(buffer.buffer),offset,length,position)}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}},llseek:function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){try{var stat=fs.fstatSync(stream.nfd);position+=stat.size}catch(e){throw new FS.ErrnoError(NODEFS.convertNodeCode(e))}}}if(position<0){throw new FS.ErrnoError(28)}return position}}};var WORKERFS={DIR_MODE:16895,FILE_MODE:33279,reader:null,mount:function(mount){assert(ENVIRONMENT_IS_WORKER);if(!WORKERFS.reader)WORKERFS.reader=new FileReaderSync;var root=WORKERFS.createNode(null,"/",WORKERFS.DIR_MODE,0);var createdParents={};function ensureParent(path){var parts=path.split("/");var parent=root;for(var i=0;i=stream.node.size)return 0;var chunk=stream.node.contents.slice(position,position+length);var ab=WORKERFS.reader.readAsArrayBuffer(chunk);buffer.set(new Uint8Array(ab),offset);return chunk.size},write:function(stream,buffer,offset,length,position){throw new FS.ErrnoError(29)},llseek:function(stream,offset,whence){var position=offset;if(whence===1){position+=stream.position}else if(whence===2){if(FS.isFile(stream.node.mode)){position+=stream.node.size}}if(position<0){throw new FS.ErrnoError(28)}return position}}};var FS={root:null,mounts:[],devices:{},streams:[],nextInode:1,nameTable:null,currentPath:"/",initialized:false,ignorePermissions:true,trackingDelegate:{},tracking:{openFlags:{READ:1,WRITE:2}},ErrnoError:null,genericErrors:{},filesystems:null,syncFSRequests:0,handleFSError:function(e){if(!(e instanceof FS.ErrnoError))throw e+" : "+stackTrace();return ___setErrNo(e.errno)},lookupPath:function(path,opts){path=PATH_FS.resolve(FS.cwd(),path);opts=opts||{};if(!path)return{path:"",node:null};var defaults={follow_mount:true,recurse_count:0};for(var key in defaults){if(opts[key]===undefined){opts[key]=defaults[key]}}if(opts.recurse_count>8){throw new FS.ErrnoError(32)}var parts=PATH.normalizeArray(path.split("/").filter(function(p){return!!p}),false);var current=FS.root;var current_path="/";for(var i=0;i40){throw new FS.ErrnoError(32)}}}}return{path:current_path,node:current}},getPath:function(node){var path;while(true){if(FS.isRoot(node)){var mount=node.mount.mountpoint;if(!path)return mount;return mount[mount.length-1]!=="/"?mount+"/"+path:mount+path}path=path?node.name+"/"+path:node.name;node=node.parent}},hashName:function(parentid,name){var hash=0;for(var i=0;i>>0)%FS.nameTable.length},hashAddNode:function(node){var hash=FS.hashName(node.parent.id,node.name);node.name_next=FS.nameTable[hash];FS.nameTable[hash]=node},hashRemoveNode:function(node){var hash=FS.hashName(node.parent.id,node.name);if(FS.nameTable[hash]===node){FS.nameTable[hash]=node.name_next}else{var current=FS.nameTable[hash];while(current){if(current.name_next===node){current.name_next=node.name_next;break}current=current.name_next}}},lookupNode:function(parent,name){var err=FS.mayLookup(parent);if(err){throw new FS.ErrnoError(err,parent)}var hash=FS.hashName(parent.id,name);for(var node=FS.nameTable[hash];node;node=node.name_next){var nodeName=node.name;if(node.parent.id===parent.id&&nodeName===name){return node}}return FS.lookup(parent,name)},createNode:function(parent,name,mode,rdev){if(!FS.FSNode){FS.FSNode=function(parent,name,mode,rdev){if(!parent){parent=this}this.parent=parent;this.mount=parent.mount;this.mounted=null;this.id=FS.nextInode++;this.name=name;this.mode=mode;this.node_ops={};this.stream_ops={};this.rdev=rdev};FS.FSNode.prototype={};var readMode=292|73;var writeMode=146;Object.defineProperties(FS.FSNode.prototype,{read:{get:function(){return(this.mode&readMode)===readMode},set:function(val){val?this.mode|=readMode:this.mode&=~readMode}},write:{get:function(){return(this.mode&writeMode)===writeMode},set:function(val){val?this.mode|=writeMode:this.mode&=~writeMode}},isFolder:{get:function(){return FS.isDir(this.mode)}},isDevice:{get:function(){return FS.isChrdev(this.mode)}}})}var node=new FS.FSNode(parent,name,mode,rdev);FS.hashAddNode(node);return node},destroyNode:function(node){FS.hashRemoveNode(node)},isRoot:function(node){return node===node.parent},isMountpoint:function(node){return!!node.mounted},isFile:function(mode){return(mode&61440)===32768},isDir:function(mode){return(mode&61440)===16384},isLink:function(mode){return(mode&61440)===40960},isChrdev:function(mode){return(mode&61440)===8192},isBlkdev:function(mode){return(mode&61440)===24576},isFIFO:function(mode){return(mode&61440)===4096},isSocket:function(mode){return(mode&49152)===49152},flagModes:{"r":0,"rs":1052672,"r+":2,"w":577,"wx":705,"xw":705,"w+":578,"wx+":706,"xw+":706,"a":1089,"ax":1217,"xa":1217,"a+":1090,"ax+":1218,"xa+":1218},modeStringToFlags:function(str){var flags=FS.flagModes[str];if(typeof flags==="undefined"){throw new Error("Unknown file open mode: "+str)}return flags},flagsToPermissionString:function(flag){var perms=["r","w","rw"][flag&3];if(flag&512){perms+="w"}return perms},nodePermissions:function(node,perms){if(FS.ignorePermissions){return 0}if(perms.indexOf("r")!==-1&&!(node.mode&292)){return 2}else if(perms.indexOf("w")!==-1&&!(node.mode&146)){return 2}else if(perms.indexOf("x")!==-1&&!(node.mode&73)){return 2}return 0},mayLookup:function(dir){var err=FS.nodePermissions(dir,"x");if(err)return err;if(!dir.node_ops.lookup)return 2;return 0},mayCreate:function(dir,name){try{var node=FS.lookupNode(dir,name);return 20}catch(e){}return FS.nodePermissions(dir,"wx")},mayDelete:function(dir,name,isdir){var node;try{node=FS.lookupNode(dir,name)}catch(e){return e.errno}var err=FS.nodePermissions(dir,"wx");if(err){return err}if(isdir){if(!FS.isDir(node.mode)){return 54}if(FS.isRoot(node)||FS.getPath(node)===FS.cwd()){return 10}}else{if(FS.isDir(node.mode)){return 31}}return 0},mayOpen:function(node,flags){if(!node){return 44}if(FS.isLink(node.mode)){return 32}else if(FS.isDir(node.mode)){if(FS.flagsToPermissionString(flags)!=="r"||flags&512){return 31}}return FS.nodePermissions(node,FS.flagsToPermissionString(flags))},MAX_OPEN_FDS:4096,nextfd:function(fd_start,fd_end){fd_start=fd_start||0;fd_end=fd_end||FS.MAX_OPEN_FDS;for(var fd=fd_start;fd<=fd_end;fd++){if(!FS.streams[fd]){return fd}}throw new FS.ErrnoError(33)},getStream:function(fd){return FS.streams[fd]},createStream:function(stream,fd_start,fd_end){if(!FS.FSStream){FS.FSStream=function(){};FS.FSStream.prototype={};Object.defineProperties(FS.FSStream.prototype,{object:{get:function(){return this.node},set:function(val){this.node=val}},isRead:{get:function(){return(this.flags&2097155)!==1}},isWrite:{get:function(){return(this.flags&2097155)!==0}},isAppend:{get:function(){return this.flags&1024}}})}var newStream=new FS.FSStream;for(var p in stream){newStream[p]=stream[p]}stream=newStream;var fd=FS.nextfd(fd_start,fd_end);stream.fd=fd;FS.streams[fd]=stream;return stream},closeStream:function(fd){FS.streams[fd]=null},chrdev_stream_ops:{open:function(stream){var device=FS.getDevice(stream.node.rdev);stream.stream_ops=device.stream_ops;if(stream.stream_ops.open){stream.stream_ops.open(stream)}},llseek:function(){throw new FS.ErrnoError(70)}},major:function(dev){return dev>>8},minor:function(dev){return dev&255},makedev:function(ma,mi){return ma<<8|mi},registerDevice:function(dev,ops){FS.devices[dev]={stream_ops:ops}},getDevice:function(dev){return FS.devices[dev]},getMounts:function(mount){var mounts=[];var check=[mount];while(check.length){var m=check.pop();mounts.push(m);check.push.apply(check,m.mounts)}return mounts},syncfs:function(populate,callback){if(typeof populate==="function"){callback=populate;populate=false}FS.syncFSRequests++;if(FS.syncFSRequests>1){console.log("warning: "+FS.syncFSRequests+" FS.syncfs operations in flight at once, probably just doing extra work")}var mounts=FS.getMounts(FS.root.mount);var completed=0;function doCallback(err){FS.syncFSRequests--;return callback(err)}function done(err){if(err){if(!done.errored){done.errored=true;return doCallback(err)}return}if(++completed>=mounts.length){doCallback(null)}}mounts.forEach(function(mount){if(!mount.type.syncfs){return done(null)}mount.type.syncfs(mount,populate,done)})},mount:function(type,opts,mountpoint){var root=mountpoint==="/";var pseudo=!mountpoint;var node;if(root&&FS.root){throw new FS.ErrnoError(10)}else if(!root&&!pseudo){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});mountpoint=lookup.path;node=lookup.node;if(FS.isMountpoint(node)){throw new FS.ErrnoError(10)}if(!FS.isDir(node.mode)){throw new FS.ErrnoError(54)}}var mount={type:type,opts:opts,mountpoint:mountpoint,mounts:[]};var mountRoot=type.mount(mount);mountRoot.mount=mount;mount.root=mountRoot;if(root){FS.root=mountRoot}else if(node){node.mounted=mount;if(node.mount){node.mount.mounts.push(mount)}}return mountRoot},unmount:function(mountpoint){var lookup=FS.lookupPath(mountpoint,{follow_mount:false});if(!FS.isMountpoint(lookup.node)){throw new FS.ErrnoError(28)}var node=lookup.node;var mount=node.mounted;var mounts=FS.getMounts(mount);Object.keys(FS.nameTable).forEach(function(hash){var current=FS.nameTable[hash];while(current){var next=current.name_next;if(mounts.indexOf(current.mount)!==-1){FS.destroyNode(current)}current=next}});node.mounted=null;var idx=node.mount.mounts.indexOf(mount);node.mount.mounts.splice(idx,1)},lookup:function(parent,name){return parent.node_ops.lookup(parent,name)},mknod:function(path,mode,dev){var lookup=FS.lookupPath(path,{parent:true});var parent=lookup.node;var name=PATH.basename(path);if(!name||name==="."||name===".."){throw new FS.ErrnoError(28)}var err=FS.mayCreate(parent,name);if(err){throw new FS.ErrnoError(err)}if(!parent.node_ops.mknod){throw new FS.ErrnoError(63)}return parent.node_ops.mknod(parent,name,mode,dev)},create:function(path,mode){mode=mode!==undefined?mode:438;mode&=4095;mode|=32768;return FS.mknod(path,mode,0)},mkdir:function(path,mode){mode=mode!==undefined?mode:511;mode&=511|512;mode|=16384;return FS.mknod(path,mode,0)},mkdirTree:function(path,mode){var dirs=path.split("/");var d="";for(var i=0;ithis.length-1||idx<0){return undefined}var chunkOffset=idx%this.chunkSize;var chunkNum=idx/this.chunkSize|0;return this.getter(chunkNum)[chunkOffset]};LazyUint8Array.prototype.setDataGetter=function LazyUint8Array_setDataGetter(getter){this.getter=getter};LazyUint8Array.prototype.cacheLength=function LazyUint8Array_cacheLength(){var xhr=new XMLHttpRequest;xhr.open("HEAD",url,false);xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);var datalength=Number(xhr.getResponseHeader("Content-length"));var header;var hasByteServing=(header=xhr.getResponseHeader("Accept-Ranges"))&&header==="bytes";var usesGzip=(header=xhr.getResponseHeader("Content-Encoding"))&&header==="gzip";var chunkSize=1024*1024;if(!hasByteServing)chunkSize=datalength;var doXHR=function(from,to){if(from>to)throw new Error("invalid range ("+from+", "+to+") or no bytes requested!");if(to>datalength-1)throw new Error("only "+datalength+" bytes available! programmer error!");var xhr=new XMLHttpRequest;xhr.open("GET",url,false);if(datalength!==chunkSize)xhr.setRequestHeader("Range","bytes="+from+"-"+to);if(typeof Uint8Array!="undefined")xhr.responseType="arraybuffer";if(xhr.overrideMimeType){xhr.overrideMimeType("text/plain; charset=x-user-defined")}xhr.send(null);if(!(xhr.status>=200&&xhr.status<300||xhr.status===304))throw new Error("Couldn't load "+url+". Status: "+xhr.status);if(xhr.response!==undefined){return new Uint8Array(xhr.response||[])}else{return intArrayFromString(xhr.responseText||"",true)}};var lazyArray=this;lazyArray.setDataGetter(function(chunkNum){var start=chunkNum*chunkSize;var end=(chunkNum+1)*chunkSize-1;end=Math.min(end,datalength-1);if(typeof lazyArray.chunks[chunkNum]==="undefined"){lazyArray.chunks[chunkNum]=doXHR(start,end)}if(typeof lazyArray.chunks[chunkNum]==="undefined")throw new Error("doXHR failed!");return lazyArray.chunks[chunkNum]});if(usesGzip||!datalength){chunkSize=datalength=1;datalength=this.getter(0).length;chunkSize=datalength;console.log("LazyFiles on gzip forces download of the whole file when length is accessed")}this._length=datalength;this._chunkSize=chunkSize;this.lengthKnown=true};if(typeof XMLHttpRequest!=="undefined"){if(!ENVIRONMENT_IS_WORKER)throw"Cannot do synchronous binary XHRs outside webworkers in modern browsers. Use --embed-file or --preload-file in emcc";var lazyArray=new LazyUint8Array;Object.defineProperties(lazyArray,{length:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._length}},chunkSize:{get:function(){if(!this.lengthKnown){this.cacheLength()}return this._chunkSize}}});var properties={isDevice:false,contents:lazyArray}}else{var properties={isDevice:false,url:url}}var node=FS.createFile(parent,name,properties,canRead,canWrite);if(properties.contents){node.contents=properties.contents}else if(properties.url){node.contents=null;node.url=properties.url}Object.defineProperties(node,{usedBytes:{get:function(){return this.contents.length}}});var stream_ops={};var keys=Object.keys(node.stream_ops);keys.forEach(function(key){var fn=node.stream_ops[key];stream_ops[key]=function forceLoadLazyFile(){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}return fn.apply(null,arguments)}});stream_ops.read=function stream_ops_read(stream,buffer,offset,length,position){if(!FS.forceLoadFile(node)){throw new FS.ErrnoError(29)}var contents=stream.node.contents;if(position>=contents.length)return 0;var size=Math.min(contents.length-position,length);if(contents.slice){for(var i=0;i>2]=stat.dev;HEAP32[buf+4>>2]=0;HEAP32[buf+8>>2]=stat.ino;HEAP32[buf+12>>2]=stat.mode;HEAP32[buf+16>>2]=stat.nlink;HEAP32[buf+20>>2]=stat.uid;HEAP32[buf+24>>2]=stat.gid;HEAP32[buf+28>>2]=stat.rdev;HEAP32[buf+32>>2]=0;tempI64=[stat.size>>>0,(tempDouble=stat.size,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+40>>2]=tempI64[0],HEAP32[buf+44>>2]=tempI64[1];HEAP32[buf+48>>2]=4096;HEAP32[buf+52>>2]=stat.blocks;HEAP32[buf+56>>2]=stat.atime.getTime()/1e3|0;HEAP32[buf+60>>2]=0;HEAP32[buf+64>>2]=stat.mtime.getTime()/1e3|0;HEAP32[buf+68>>2]=0;HEAP32[buf+72>>2]=stat.ctime.getTime()/1e3|0;HEAP32[buf+76>>2]=0;tempI64=[stat.ino>>>0,(tempDouble=stat.ino,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[buf+80>>2]=tempI64[0],HEAP32[buf+84>>2]=tempI64[1];return 0},doMsync:function(addr,stream,len,flags){var buffer=new Uint8Array(HEAPU8.subarray(addr,addr+len));FS.msync(stream,buffer,0,len,flags)},doMkdir:function(path,mode){path=PATH.normalize(path);if(path[path.length-1]==="/")path=path.substr(0,path.length-1);FS.mkdir(path,mode,0);return 0},doMknod:function(path,mode,dev){switch(mode&61440){case 32768:case 8192:case 24576:case 4096:case 49152:break;default:return-28}FS.mknod(path,mode,dev);return 0},doReadlink:function(path,buf,bufsize){if(bufsize<=0)return-28;var ret=FS.readlink(path);var len=Math.min(bufsize,lengthBytesUTF8(ret));var endChar=HEAP8[buf+len];stringToUTF8(ret,buf,bufsize+1);HEAP8[buf+len]=endChar;return len},doAccess:function(path,amode){if(amode&~7){return-28}var node;var lookup=FS.lookupPath(path,{follow:true});node=lookup.node;if(!node){return-44}var perms="";if(amode&4)perms+="r";if(amode&2)perms+="w";if(amode&1)perms+="x";if(perms&&FS.nodePermissions(node,perms)){return-2}return 0},doDup:function(path,flags,suggestFD){var suggest=FS.getStream(suggestFD);if(suggest)FS.close(suggest);return FS.open(path,flags,0,suggestFD,suggestFD).fd},doReadv:function(stream,iov,iovcnt,offset){var ret=0;for(var i=0;i>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.read(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr;if(curr>2];var len=HEAP32[iov+(i*8+4)>>2];var curr=FS.write(stream,HEAP8,ptr,len,offset);if(curr<0)return-1;ret+=curr}return ret},varargs:0,get:function(varargs){SYSCALLS.varargs+=4;var ret=HEAP32[SYSCALLS.varargs-4>>2];return ret},getStr:function(){var ret=UTF8ToString(SYSCALLS.get());return ret},getStreamFromFD:function(fd){if(fd===undefined)fd=SYSCALLS.get();var stream=FS.getStream(fd);if(!stream)throw new FS.ErrnoError(8);return stream},get64:function(){var low=SYSCALLS.get(),high=SYSCALLS.get();return low},getZero:function(){SYSCALLS.get()}};function ___syscall10(which,varargs){SYSCALLS.varargs=varargs;try{var path=SYSCALLS.getStr();FS.unlink(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall221(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),cmd=SYSCALLS.get();switch(cmd){case 0:{var arg=SYSCALLS.get();if(arg<0){return-28}var newStream;newStream=FS.open(stream.path,stream.flags,0,arg);return newStream.fd}case 1:case 2:return 0;case 3:return stream.flags;case 4:{var arg=SYSCALLS.get();stream.flags|=arg;return 0}case 12:{var arg=SYSCALLS.get();var offset=0;HEAP16[arg+offset>>1]=2;return 0}case 13:case 14:return 0;case 16:case 8:return-28;case 9:___setErrNo(28);return-1;default:{return-28}}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall40(which,varargs){SYSCALLS.varargs=varargs;try{var path=SYSCALLS.getStr();FS.rmdir(path);return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall5(which,varargs){SYSCALLS.varargs=varargs;try{var pathname=SYSCALLS.getStr(),flags=SYSCALLS.get(),mode=SYSCALLS.get();var stream=FS.open(pathname,flags,mode);return stream.fd}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___syscall54(which,varargs){SYSCALLS.varargs=varargs;try{var stream=SYSCALLS.getStreamFromFD(),op=SYSCALLS.get();switch(op){case 21509:case 21505:{if(!stream.tty)return-59;return 0}case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:{if(!stream.tty)return-59;return 0}case 21519:{if(!stream.tty)return-59;var argp=SYSCALLS.get();HEAP32[argp>>2]=0;return 0}case 21520:{if(!stream.tty)return-59;return-28}case 21531:{var argp=SYSCALLS.get();return FS.ioctl(stream,op,argp)}case 21523:{if(!stream.tty)return-59;return 0}case 21524:{if(!stream.tty)return-59;return 0}default:abort("bad ioctl syscall "+op)}}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function __emscripten_syscall_munmap(addr,len){if(addr===-1||len===0){return-28}var info=SYSCALLS.mappings[addr];if(!info)return 0;if(len===info.len){var stream=FS.getStream(info.fd);SYSCALLS.doMsync(addr,stream,len,info.flags);FS.munmap(stream);SYSCALLS.mappings[addr]=null;if(info.allocated){_free(info.malloc)}}return 0}function ___syscall91(which,varargs){SYSCALLS.varargs=varargs;try{var addr=SYSCALLS.get(),len=SYSCALLS.get();return __emscripten_syscall_munmap(addr,len)}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return-e.errno}}function ___unlock(){}function _abort(){abort()}function _emscripten_get_heap_size(){return HEAP8.length}var setjmpId=0;function _saveSetjmp(env,label,table,size){env=env|0;label=label|0;table=table|0;size=size|0;var i=0;setjmpId=setjmpId+1|0;HEAP32[env>>2]=setjmpId;while((i|0)<(size|0)){if((HEAP32[table+(i<<3)>>2]|0)==0){HEAP32[table+(i<<3)>>2]=setjmpId;HEAP32[table+((i<<3)+4)>>2]=label;HEAP32[table+((i<<3)+8)>>2]=0;setTempRet0(size|0);return table|0}i=i+1|0}size=size*2|0;table=_realloc(table|0,8*(size+1|0)|0)|0;table=_saveSetjmp(env|0,label|0,table|0,size|0)|0;setTempRet0(size|0);return table|0}function _testSetjmp(id,table,size){id=id|0;table=table|0;size=size|0;var i=0,curr=0;while((i|0)<(size|0)){curr=HEAP32[table+(i<<3)>>2]|0;if((curr|0)==0)break;if((curr|0)==(id|0)){return HEAP32[table+((i<<3)+4)>>2]|0}i=i+1|0}return 0}function _longjmp(env,value){_setThrew(env,value||1);throw"longjmp"}function _emscripten_longjmp(env,value){_longjmp(env,value)}function _emscripten_memcpy_big(dest,src,num){HEAPU8.set(HEAPU8.subarray(src,src+num),dest)}function emscripten_realloc_buffer(size){try{wasmMemory.grow(size-buffer.byteLength+65535>>16);updateGlobalBufferAndViews(wasmMemory.buffer);return 1}catch(e){}}function _emscripten_resize_heap(requestedSize){var oldSize=_emscripten_get_heap_size();var PAGE_MULTIPLE=65536;var LIMIT=2147483648-PAGE_MULTIPLE;if(requestedSize>LIMIT){return false}var MIN_TOTAL_MEMORY=16777216;var newSize=Math.max(oldSize,MIN_TOTAL_MEMORY);while(newSize>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_seek(fd,offset_low,offset_high,whence,newOffset){try{var stream=SYSCALLS.getStreamFromFD(fd);var HIGH_OFFSET=4294967296;var offset=offset_high*HIGH_OFFSET+(offset_low>>>0);var DOUBLE_LIMIT=9007199254740992;if(offset<=-DOUBLE_LIMIT||offset>=DOUBLE_LIMIT){return-61}FS.llseek(stream,offset,whence);tempI64=[stream.position>>>0,(tempDouble=stream.position,+Math_abs(tempDouble)>=1?tempDouble>0?(Math_min(+Math_floor(tempDouble/4294967296),4294967295)|0)>>>0:~~+Math_ceil((tempDouble-+(~~tempDouble>>>0))/4294967296)>>>0:0)],HEAP32[newOffset>>2]=tempI64[0],HEAP32[newOffset+4>>2]=tempI64[1];if(stream.getdents&&offset===0&&whence===0)stream.getdents=null;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _fd_write(fd,iov,iovcnt,pnum){try{var stream=SYSCALLS.getStreamFromFD(fd);var num=SYSCALLS.doWritev(stream,iov,iovcnt);HEAP32[pnum>>2]=num;return 0}catch(e){if(typeof FS==="undefined"||!(e instanceof FS.ErrnoError))abort(e);return e.errno}}function _getTempRet0(){return getTempRet0()|0}function _gettimeofday(ptr){var now=Date.now();HEAP32[ptr>>2]=now/1e3|0;HEAP32[ptr+4>>2]=now%1e3*1e3|0;return 0}function _pthread_attr_init(attr){return 0}function _pthread_attr_setdetachstate(){}function _pthread_cond_destroy(){return 0}function _pthread_cond_init(){return 0}function _pthread_create(){return 6}function _pthread_join(){}function _pthread_mutexattr_destroy(){}function _pthread_mutexattr_init(){}function _pthread_mutexattr_settype(){}function _round(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}function _roundf(d){d=+d;return d>=+0?+Math_floor(d+ +.5):+Math_ceil(d-+.5)}function _setTempRet0($i){setTempRet0($i|0)}function __isLeapYear(year){return year%4===0&&(year%100!==0||year%400===0)}function __arraySum(array,index){var sum=0;for(var i=0;i<=index;sum+=array[i++]);return sum}var __MONTH_DAYS_LEAP=[31,29,31,30,31,30,31,31,30,31,30,31];var __MONTH_DAYS_REGULAR=[31,28,31,30,31,30,31,31,30,31,30,31];function __addDays(date,days){var newDate=new Date(date.getTime());while(days>0){var leap=__isLeapYear(newDate.getFullYear());var currentMonth=newDate.getMonth();var daysInCurrentMonth=(leap?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR)[currentMonth];if(days>daysInCurrentMonth-newDate.getDate()){days-=daysInCurrentMonth-newDate.getDate()+1;newDate.setDate(1);if(currentMonth<11){newDate.setMonth(currentMonth+1)}else{newDate.setMonth(0);newDate.setFullYear(newDate.getFullYear()+1)}}else{newDate.setDate(newDate.getDate()+days);return newDate}}return newDate}function _strftime(s,maxsize,format,tm){var tm_zone=HEAP32[tm+40>>2];var date={tm_sec:HEAP32[tm>>2],tm_min:HEAP32[tm+4>>2],tm_hour:HEAP32[tm+8>>2],tm_mday:HEAP32[tm+12>>2],tm_mon:HEAP32[tm+16>>2],tm_year:HEAP32[tm+20>>2],tm_wday:HEAP32[tm+24>>2],tm_yday:HEAP32[tm+28>>2],tm_isdst:HEAP32[tm+32>>2],tm_gmtoff:HEAP32[tm+36>>2],tm_zone:tm_zone?UTF8ToString(tm_zone):""};var pattern=UTF8ToString(format);var EXPANSION_RULES_1={"%c":"%a %b %d %H:%M:%S %Y","%D":"%m/%d/%y","%F":"%Y-%m-%d","%h":"%b","%r":"%I:%M:%S %p","%R":"%H:%M","%T":"%H:%M:%S","%x":"%m/%d/%y","%X":"%H:%M:%S","%Ec":"%c","%EC":"%C","%Ex":"%m/%d/%y","%EX":"%H:%M:%S","%Ey":"%y","%EY":"%Y","%Od":"%d","%Oe":"%e","%OH":"%H","%OI":"%I","%Om":"%m","%OM":"%M","%OS":"%S","%Ou":"%u","%OU":"%U","%OV":"%V","%Ow":"%w","%OW":"%W","%Oy":"%y"};for(var rule in EXPANSION_RULES_1){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_1[rule])}var WEEKDAYS=["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"];var MONTHS=["January","February","March","April","May","June","July","August","September","October","November","December"];function leadingSomething(value,digits,character){var str=typeof value==="number"?value.toString():value||"";while(str.length0?1:0}var compare;if((compare=sgn(date1.getFullYear()-date2.getFullYear()))===0){if((compare=sgn(date1.getMonth()-date2.getMonth()))===0){compare=sgn(date1.getDate()-date2.getDate())}}return compare}function getFirstWeekStartDate(janFourth){switch(janFourth.getDay()){case 0:return new Date(janFourth.getFullYear()-1,11,29);case 1:return janFourth;case 2:return new Date(janFourth.getFullYear(),0,3);case 3:return new Date(janFourth.getFullYear(),0,2);case 4:return new Date(janFourth.getFullYear(),0,1);case 5:return new Date(janFourth.getFullYear()-1,11,31);case 6:return new Date(janFourth.getFullYear()-1,11,30)}}function getWeekBasedYear(date){var thisDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);var janFourthThisYear=new Date(thisDate.getFullYear(),0,4);var janFourthNextYear=new Date(thisDate.getFullYear()+1,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);if(compareByDay(firstWeekStartThisYear,thisDate)<=0){if(compareByDay(firstWeekStartNextYear,thisDate)<=0){return thisDate.getFullYear()+1}else{return thisDate.getFullYear()}}else{return thisDate.getFullYear()-1}}var EXPANSION_RULES_2={"%a":function(date){return WEEKDAYS[date.tm_wday].substring(0,3)},"%A":function(date){return WEEKDAYS[date.tm_wday]},"%b":function(date){return MONTHS[date.tm_mon].substring(0,3)},"%B":function(date){return MONTHS[date.tm_mon]},"%C":function(date){var year=date.tm_year+1900;return leadingNulls(year/100|0,2)},"%d":function(date){return leadingNulls(date.tm_mday,2)},"%e":function(date){return leadingSomething(date.tm_mday,2," ")},"%g":function(date){return getWeekBasedYear(date).toString().substring(2)},"%G":function(date){return getWeekBasedYear(date)},"%H":function(date){return leadingNulls(date.tm_hour,2)},"%I":function(date){var twelveHour=date.tm_hour;if(twelveHour==0)twelveHour=12;else if(twelveHour>12)twelveHour-=12;return leadingNulls(twelveHour,2)},"%j":function(date){return leadingNulls(date.tm_mday+__arraySum(__isLeapYear(date.tm_year+1900)?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,date.tm_mon-1),3)},"%m":function(date){return leadingNulls(date.tm_mon+1,2)},"%M":function(date){return leadingNulls(date.tm_min,2)},"%n":function(){return"\n"},"%p":function(date){if(date.tm_hour>=0&&date.tm_hour<12){return"AM"}else{return"PM"}},"%S":function(date){return leadingNulls(date.tm_sec,2)},"%t":function(){return"\t"},"%u":function(date){return date.tm_wday||7},"%U":function(date){var janFirst=new Date(date.tm_year+1900,0,1);var firstSunday=janFirst.getDay()===0?janFirst:__addDays(janFirst,7-janFirst.getDay());var endDate=new Date(date.tm_year+1900,date.tm_mon,date.tm_mday);if(compareByDay(firstSunday,endDate)<0){var februaryFirstUntilEndMonth=__arraySum(__isLeapYear(endDate.getFullYear())?__MONTH_DAYS_LEAP:__MONTH_DAYS_REGULAR,endDate.getMonth()-1)-31;var firstSundayUntilEndJanuary=31-firstSunday.getDate();var days=firstSundayUntilEndJanuary+februaryFirstUntilEndMonth+endDate.getDate();return leadingNulls(Math.ceil(days/7),2)}return compareByDay(firstSunday,janFirst)===0?"01":"00"},"%V":function(date){var janFourthThisYear=new Date(date.tm_year+1900,0,4);var janFourthNextYear=new Date(date.tm_year+1901,0,4);var firstWeekStartThisYear=getFirstWeekStartDate(janFourthThisYear);var firstWeekStartNextYear=getFirstWeekStartDate(janFourthNextYear);var endDate=__addDays(new Date(date.tm_year+1900,0,1),date.tm_yday);if(compareByDay(endDate,firstWeekStartThisYear)<0){return"53"}if(compareByDay(firstWeekStartNextYear,endDate)<=0){return"01"}var daysDifference;if(firstWeekStartThisYear.getFullYear()=0;off=Math.abs(off)/60;off=off/60*100+off%60;return(ahead?"+":"-")+String("0000"+off).slice(-4)},"%Z":function(date){return date.tm_zone},"%%":function(){return"%"}};for(var rule in EXPANSION_RULES_2){if(pattern.indexOf(rule)>=0){pattern=pattern.replace(new RegExp(rule,"g"),EXPANSION_RULES_2[rule](date))}}var bytes=intArrayFromString(pattern,false);if(bytes.length>maxsize){return 0}writeArrayToMemory(bytes,s);return bytes.length-1}function _strftime_l(s,maxsize,format,tm){return _strftime(s,maxsize,format,tm)}function _sysconf(name){switch(name){case 30:return PAGE_SIZE;case 85:var maxHeapSize=2*1024*1024*1024-65536;return maxHeapSize/PAGE_SIZE;case 132:case 133:case 12:case 137:case 138:case 15:case 235:case 16:case 17:case 18:case 19:case 20:case 149:case 13:case 10:case 236:case 153:case 9:case 21:case 22:case 159:case 154:case 14:case 77:case 78:case 139:case 80:case 81:case 82:case 68:case 67:case 164:case 11:case 29:case 47:case 48:case 95:case 52:case 51:case 46:return 200809;case 79:return 0;case 27:case 246:case 127:case 128:case 23:case 24:case 160:case 161:case 181:case 182:case 242:case 183:case 184:case 243:case 244:case 245:case 165:case 178:case 179:case 49:case 50:case 168:case 169:case 175:case 170:case 171:case 172:case 97:case 76:case 32:case 173:case 35:return-1;case 176:case 177:case 7:case 155:case 8:case 157:case 125:case 126:case 92:case 93:case 129:case 130:case 131:case 94:case 91:return 1;case 74:case 60:case 69:case 70:case 4:return 1024;case 31:case 42:case 72:return 32;case 87:case 26:case 33:return 2147483647;case 34:case 1:return 47839;case 38:case 36:return 99;case 43:case 37:return 2048;case 0:return 2097152;case 3:return 65536;case 28:return 32768;case 44:return 32767;case 75:return 16384;case 39:return 1e3;case 89:return 700;case 71:return 256;case 40:return 255;case 2:return 100;case 180:return 64;case 25:return 20;case 5:return 16;case 6:return 6;case 73:return 4;case 84:{if(typeof navigator==="object")return navigator["hardwareConcurrency"]||1;return 1}}___setErrNo(28);return-1}if(ENVIRONMENT_IS_NODE){_emscripten_get_now=function _emscripten_get_now_actual(){var t=process["hrtime"]();return t[0]*1e3+t[1]/1e6}}else if(typeof dateNow!=="undefined"){_emscripten_get_now=dateNow}else if(typeof performance==="object"&&performance&&typeof performance["now"]==="function"){_emscripten_get_now=function(){return performance["now"]()}}else{_emscripten_get_now=Date.now}FS.staticInit();if(ENVIRONMENT_HAS_NODE){var fs=require("fs");var NODEJS_PATH=require("path");NODEFS.staticInit()}function intArrayFromString(stringy,dontAddNull,length){var len=length>0?length:lengthBytesUTF8(stringy)+1;var u8array=new Array(len);var numBytesWritten=stringToUTF8Array(stringy,u8array,0,u8array.length);if(dontAddNull)u8array.length=numBytesWritten;return u8array}var asmLibraryArg={"M":___clock_gettime,"d":___cxa_allocate_exception,"e":___cxa_throw,"w":___lock,"J":___map_file,"R":___syscall10,"y":___syscall221,"Q":___syscall40,"z":___syscall5,"P":___syscall54,"I":___syscall91,"o":___unlock,"m":_abort,"g":_emscripten_longjmp,"C":_emscripten_memcpy_big,"D":_emscripten_resize_heap,"K":_environ_get,"L":_environ_sizes_get,"X":_exit,"r":_fd_close,"O":_fd_read,"B":_fd_seek,"N":_fd_write,"a":_getTempRet0,"F":_gettimeofday,"h":invoke_ii,"j":invoke_iii,"p":invoke_iiii,"u":invoke_iiiii,"_":invoke_iiiiii,"$":invoke_iiiiiiiiii,"f":invoke_vi,"i":invoke_vii,"Z":invoke_viidd,"k":invoke_viii,"t":invoke_viiii,"q":invoke_viiiii,"aa":invoke_viiiiii,"Y":invoke_viiiiiiiii,"memory":wasmMemory,"W":_pthread_attr_init,"V":_pthread_attr_setdetachstate,"s":_pthread_cond_destroy,"A":_pthread_cond_init,"T":_pthread_create,"S":_pthread_join,"v":_pthread_mutexattr_destroy,"G":_pthread_mutexattr_init,"E":_pthread_mutexattr_settype,"n":_round,"U":_roundf,"l":_saveSetjmp,"b":_setTempRet0,"H":_strftime_l,"x":_sysconf,"table":wasmTable,"c":_testSetjmp};var asm=createWasm();Module["asm"]=asm;var ___wasm_call_ctors=Module["___wasm_call_ctors"]=function(){return Module["asm"]["ba"].apply(null,arguments)};var _get_info=Module["_get_info"]=function(){return Module["asm"]["ca"].apply(null,arguments)};var _load_server=Module["_load_server"]=function(){return Module["asm"]["da"].apply(null,arguments)};var _load_json=Module["_load_json"]=function(){return Module["asm"]["ea"].apply(null,arguments)};var _load_templ=Module["_load_templ"]=function(){return Module["asm"]["fa"].apply(null,arguments)};var _recognize=Module["_recognize"]=function(){return Module["asm"]["ga"].apply(null,arguments)};var _free=Module["_free"]=function(){return Module["asm"]["ha"].apply(null,arguments)};var ___errno_location=Module["___errno_location"]=function(){return Module["asm"]["ia"].apply(null,arguments)};var _malloc=Module["_malloc"]=function(){return Module["asm"]["ja"].apply(null,arguments)};var _realloc=Module["_realloc"]=function(){return Module["asm"]["ka"].apply(null,arguments)};var _setThrew=Module["_setThrew"]=function(){return Module["asm"]["la"].apply(null,arguments)};var __ZSt18uncaught_exceptionv=Module["__ZSt18uncaught_exceptionv"]=function(){return Module["asm"]["ma"].apply(null,arguments)};var dynCall_ii=Module["dynCall_ii"]=function(){return Module["asm"]["na"].apply(null,arguments)};var dynCall_iii=Module["dynCall_iii"]=function(){return Module["asm"]["oa"].apply(null,arguments)};var dynCall_iiii=Module["dynCall_iiii"]=function(){return Module["asm"]["pa"].apply(null,arguments)};var dynCall_iiiii=Module["dynCall_iiiii"]=function(){return Module["asm"]["qa"].apply(null,arguments)};var dynCall_iiiiii=Module["dynCall_iiiiii"]=function(){return Module["asm"]["ra"].apply(null,arguments)};var dynCall_iiiiiiiiii=Module["dynCall_iiiiiiiiii"]=function(){return Module["asm"]["sa"].apply(null,arguments)};var dynCall_vi=Module["dynCall_vi"]=function(){return Module["asm"]["ta"].apply(null,arguments)};var dynCall_vii=Module["dynCall_vii"]=function(){return Module["asm"]["ua"].apply(null,arguments)};var dynCall_viidd=Module["dynCall_viidd"]=function(){return Module["asm"]["va"].apply(null,arguments)};var dynCall_viii=Module["dynCall_viii"]=function(){return Module["asm"]["wa"].apply(null,arguments)};var dynCall_viiii=Module["dynCall_viiii"]=function(){return Module["asm"]["xa"].apply(null,arguments)};var dynCall_viiiii=Module["dynCall_viiiii"]=function(){return Module["asm"]["ya"].apply(null,arguments)};var dynCall_viiiiii=Module["dynCall_viiiiii"]=function(){return Module["asm"]["za"].apply(null,arguments)};var dynCall_viiiiiiiii=Module["dynCall_viiiiiiiii"]=function(){return Module["asm"]["Aa"].apply(null,arguments)};var stackSave=Module["stackSave"]=function(){return Module["asm"]["Ba"].apply(null,arguments)};var stackAlloc=Module["stackAlloc"]=function(){return Module["asm"]["Ca"].apply(null,arguments)};var stackRestore=Module["stackRestore"]=function(){return Module["asm"]["Da"].apply(null,arguments)};var dynCall_v=Module["dynCall_v"]=function(){return Module["asm"]["Ea"].apply(null,arguments)};function invoke_vi(index,a1){var sp=stackSave();try{dynCall_vi(index,a1)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_ii(index,a1){var sp=stackSave();try{return dynCall_ii(index,a1)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viii(index,a1,a2,a3){var sp=stackSave();try{dynCall_viii(index,a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_iii(index,a1,a2){var sp=stackSave();try{return dynCall_iii(index,a1,a2)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_vii(index,a1,a2){var sp=stackSave();try{dynCall_vii(index,a1,a2)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_iiiii(index,a1,a2,a3,a4){var sp=stackSave();try{return dynCall_iiiii(index,a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_iiii(index,a1,a2,a3){var sp=stackSave();try{return dynCall_iiii(index,a1,a2,a3)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{dynCall_viiiii(index,a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viiiiii(index,a1,a2,a3,a4,a5,a6){var sp=stackSave();try{dynCall_viiiiii(index,a1,a2,a3,a4,a5,a6)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_iiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{return dynCall_iiiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_iiiiii(index,a1,a2,a3,a4,a5){var sp=stackSave();try{return dynCall_iiiiii(index,a1,a2,a3,a4,a5)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viidd(index,a1,a2,a3,a4){var sp=stackSave();try{dynCall_viidd(index,a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viiii(index,a1,a2,a3,a4){var sp=stackSave();try{dynCall_viiii(index,a1,a2,a3,a4)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}function invoke_viiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9){var sp=stackSave();try{dynCall_viiiiiiiii(index,a1,a2,a3,a4,a5,a6,a7,a8,a9)}catch(e){stackRestore(sp);if(e!==e+0&&e!=="longjmp")throw e;_setThrew(1,0)}}Module["asm"]=asm;Module["cwrap"]=cwrap;var calledRun;function ExitStatus(status){this.name="ExitStatus";this.message="Program terminated with exit("+status+")";this.status=status}dependenciesFulfilled=function runCaller(){if(!calledRun)run();if(!calledRun)dependenciesFulfilled=runCaller};function run(args){args=args||arguments_;if(runDependencies>0){return}preRun();if(runDependencies>0)return;function doRun(){if(calledRun)return;calledRun=true;if(ABORT)return;initRuntime();preMain();if(Module["onRuntimeInitialized"])Module["onRuntimeInitialized"]();postRun()}if(Module["setStatus"]){Module["setStatus"]("Running...");setTimeout(function(){setTimeout(function(){Module["setStatus"]("")},1);doRun()},1)}else{doRun()}}Module["run"]=run;function exit(status,implicit){if(implicit&&noExitRuntime&&status===0){return}if(noExitRuntime){}else{ABORT=true;EXITSTATUS=status;exitRuntime();if(Module["onExit"])Module["onExit"](status)}quit_(status,new ExitStatus(status))}if(Module["preInit"]){if(typeof Module["preInit"]=="function")Module["preInit"]=[Module["preInit"]];while(Module["preInit"].length>0){Module["preInit"].pop()()}}noExitRuntime=true;run(); diff --git a/public/penguin.wasm b/public/penguin.wasm new file mode 100644 index 00000000..27079670 Binary files /dev/null and b/public/penguin.wasm differ diff --git a/resources/android/icon-background.png b/resources/android/icon-background.png new file mode 100644 index 00000000..27c88a30 Binary files /dev/null and b/resources/android/icon-background.png differ diff --git a/resources/android/icon-foreground.png b/resources/android/icon-foreground.png new file mode 100644 index 00000000..ad286151 Binary files /dev/null and b/resources/android/icon-foreground.png differ diff --git a/resources/android/icon/drawable-hdpi-icon.png b/resources/android/icon/drawable-hdpi-icon.png index 116814ae..1fee6a9e 100644 Binary files a/resources/android/icon/drawable-hdpi-icon.png and b/resources/android/icon/drawable-hdpi-icon.png differ diff --git a/resources/android/icon/drawable-ldpi-icon.png b/resources/android/icon/drawable-ldpi-icon.png index 2484485f..0f264e95 100644 Binary files a/resources/android/icon/drawable-ldpi-icon.png and b/resources/android/icon/drawable-ldpi-icon.png differ diff --git a/resources/android/icon/drawable-mdpi-icon.png b/resources/android/icon/drawable-mdpi-icon.png index b4c66b53..e77f08de 100644 Binary files a/resources/android/icon/drawable-mdpi-icon.png and b/resources/android/icon/drawable-mdpi-icon.png differ diff --git a/resources/android/icon/drawable-xhdpi-icon.png b/resources/android/icon/drawable-xhdpi-icon.png index 5cf34eef..291267d4 100644 Binary files a/resources/android/icon/drawable-xhdpi-icon.png and b/resources/android/icon/drawable-xhdpi-icon.png differ diff --git a/resources/android/icon/drawable-xxhdpi-icon.png b/resources/android/icon/drawable-xxhdpi-icon.png index 2e771977..62015e2a 100644 Binary files a/resources/android/icon/drawable-xxhdpi-icon.png and b/resources/android/icon/drawable-xxhdpi-icon.png differ diff --git a/resources/android/icon/drawable-xxxhdpi-icon.png b/resources/android/icon/drawable-xxxhdpi-icon.png index 02746b41..8af0b65d 100644 Binary files a/resources/android/icon/drawable-xxxhdpi-icon.png and b/resources/android/icon/drawable-xxxhdpi-icon.png differ diff --git a/resources/android/icon/hdpi-background.png b/resources/android/icon/hdpi-background.png new file mode 100644 index 00000000..07fcd8cc Binary files /dev/null and b/resources/android/icon/hdpi-background.png differ diff --git a/resources/android/icon/hdpi-foreground.png b/resources/android/icon/hdpi-foreground.png new file mode 100644 index 00000000..caf72047 Binary files /dev/null and b/resources/android/icon/hdpi-foreground.png differ diff --git a/resources/android/icon/ldpi-background.png b/resources/android/icon/ldpi-background.png new file mode 100644 index 00000000..948f63b7 Binary files /dev/null and b/resources/android/icon/ldpi-background.png differ diff --git a/resources/android/icon/ldpi-foreground.png b/resources/android/icon/ldpi-foreground.png new file mode 100644 index 00000000..e56b7ad9 Binary files /dev/null and b/resources/android/icon/ldpi-foreground.png differ diff --git a/resources/android/icon/mdpi-background.png b/resources/android/icon/mdpi-background.png new file mode 100644 index 00000000..a17f704c Binary files /dev/null and b/resources/android/icon/mdpi-background.png differ diff --git a/resources/android/icon/mdpi-foreground.png b/resources/android/icon/mdpi-foreground.png new file mode 100644 index 00000000..63c01ca6 Binary files /dev/null and b/resources/android/icon/mdpi-foreground.png differ diff --git a/resources/android/icon/xhdpi-background.png b/resources/android/icon/xhdpi-background.png new file mode 100644 index 00000000..d44d316d Binary files /dev/null and b/resources/android/icon/xhdpi-background.png differ diff --git a/resources/android/icon/xhdpi-foreground.png b/resources/android/icon/xhdpi-foreground.png new file mode 100644 index 00000000..22cc07e9 Binary files /dev/null and b/resources/android/icon/xhdpi-foreground.png differ diff --git a/resources/android/icon/xxhdpi-background.png b/resources/android/icon/xxhdpi-background.png new file mode 100644 index 00000000..aada66f1 Binary files /dev/null and b/resources/android/icon/xxhdpi-background.png differ diff --git a/resources/android/icon/xxhdpi-foreground.png b/resources/android/icon/xxhdpi-foreground.png new file mode 100644 index 00000000..94e893b8 Binary files /dev/null and b/resources/android/icon/xxhdpi-foreground.png differ diff --git a/resources/android/icon/xxxhdpi-background.png b/resources/android/icon/xxxhdpi-background.png new file mode 100644 index 00000000..791b5645 Binary files /dev/null and b/resources/android/icon/xxxhdpi-background.png differ diff --git a/resources/android/icon/xxxhdpi-foreground.png b/resources/android/icon/xxxhdpi-foreground.png new file mode 100644 index 00000000..bba94de4 Binary files /dev/null and b/resources/android/icon/xxxhdpi-foreground.png differ diff --git a/resources/android/splash/drawable-land-hdpi-screen.png b/resources/android/splash/drawable-land-hdpi-screen.png index d395e71d..edca8d2d 100644 Binary files a/resources/android/splash/drawable-land-hdpi-screen.png and b/resources/android/splash/drawable-land-hdpi-screen.png differ diff --git a/resources/android/splash/drawable-land-ldpi-screen.png b/resources/android/splash/drawable-land-ldpi-screen.png index 0b82c97f..fbec0cb0 100644 Binary files a/resources/android/splash/drawable-land-ldpi-screen.png and b/resources/android/splash/drawable-land-ldpi-screen.png differ diff --git a/resources/android/splash/drawable-land-mdpi-screen.png b/resources/android/splash/drawable-land-mdpi-screen.png index cb8cc4bf..ade38f86 100644 Binary files a/resources/android/splash/drawable-land-mdpi-screen.png and b/resources/android/splash/drawable-land-mdpi-screen.png differ diff --git a/resources/android/splash/drawable-land-xhdpi-screen.png b/resources/android/splash/drawable-land-xhdpi-screen.png index f18b610d..a582e1c3 100644 Binary files a/resources/android/splash/drawable-land-xhdpi-screen.png and b/resources/android/splash/drawable-land-xhdpi-screen.png differ diff --git a/resources/android/splash/drawable-land-xxhdpi-screen.png b/resources/android/splash/drawable-land-xxhdpi-screen.png index d24d77ee..caae83f5 100644 Binary files a/resources/android/splash/drawable-land-xxhdpi-screen.png and b/resources/android/splash/drawable-land-xxhdpi-screen.png differ diff --git a/resources/android/splash/drawable-land-xxxhdpi-screen.png b/resources/android/splash/drawable-land-xxxhdpi-screen.png index 0c524929..a7edef4e 100644 Binary files a/resources/android/splash/drawable-land-xxxhdpi-screen.png and b/resources/android/splash/drawable-land-xxxhdpi-screen.png differ diff --git a/resources/android/splash/drawable-port-hdpi-screen.png b/resources/android/splash/drawable-port-hdpi-screen.png index 963d9b6e..49f08064 100644 Binary files a/resources/android/splash/drawable-port-hdpi-screen.png and b/resources/android/splash/drawable-port-hdpi-screen.png differ diff --git a/resources/android/splash/drawable-port-ldpi-screen.png b/resources/android/splash/drawable-port-ldpi-screen.png index 5ddbbf49..a6862007 100644 Binary files a/resources/android/splash/drawable-port-ldpi-screen.png and b/resources/android/splash/drawable-port-ldpi-screen.png differ diff --git a/resources/android/splash/drawable-port-mdpi-screen.png b/resources/android/splash/drawable-port-mdpi-screen.png index be2a7cca..bebfc494 100644 Binary files a/resources/android/splash/drawable-port-mdpi-screen.png and b/resources/android/splash/drawable-port-mdpi-screen.png differ diff --git a/resources/android/splash/drawable-port-xhdpi-screen.png b/resources/android/splash/drawable-port-xhdpi-screen.png index 61485ab9..fb8bd434 100644 Binary files a/resources/android/splash/drawable-port-xhdpi-screen.png and b/resources/android/splash/drawable-port-xhdpi-screen.png differ diff --git a/resources/android/splash/drawable-port-xxhdpi-screen.png b/resources/android/splash/drawable-port-xxhdpi-screen.png index fbae5aba..332ff320 100644 Binary files a/resources/android/splash/drawable-port-xxhdpi-screen.png and b/resources/android/splash/drawable-port-xxhdpi-screen.png differ diff --git a/resources/android/splash/drawable-port-xxxhdpi-screen.png b/resources/android/splash/drawable-port-xxxhdpi-screen.png index 034151ef..584010af 100644 Binary files a/resources/android/splash/drawable-port-xxxhdpi-screen.png and b/resources/android/splash/drawable-port-xxxhdpi-screen.png differ diff --git a/src/App.vue b/src/App.vue index fcdf6349..7acb40ec 100644 --- a/src/App.vue +++ b/src/App.vue @@ -67,14 +67,22 @@ + + + + + + + diff --git a/src/apis/external.js b/src/apis/external.js index 4455297d..c0836470 100644 --- a/src/apis/external.js +++ b/src/apis/external.js @@ -1,7 +1,7 @@ -import {externalService} from '@/utils/service' +import { externalService } from '@/utils/service' export default { geoip () { - return externalService.get("https://api.ip.sb/geoip") + return externalService.get('https://api.ip.sb/geoip') } -} \ No newline at end of file +} diff --git a/src/apis/meta.js b/src/apis/meta.js index 595a90e2..bfe307c0 100644 --- a/src/apis/meta.js +++ b/src/apis/meta.js @@ -1,7 +1,7 @@ -import {service} from '@/utils/service' +import { service } from '@/utils/service' export default { getNotice (data) { - return service.get("/notice", data) + return service.get('/notice', data) } -} \ No newline at end of file +} diff --git a/src/apis/planner.js b/src/apis/planner.js index 87bb7b8d..92f7df6e 100644 --- a/src/apis/planner.js +++ b/src/apis/planner.js @@ -1,7 +1,7 @@ -import {externalService} from '@/utils/service' +import { externalService } from '@/utils/service' export default { plan (data) { - return externalService.post("https://planner.penguin-stats.io/plan", data) + return externalService.post('https://planner.penguin-stats.io/plan', data) } -} \ No newline at end of file +} diff --git a/src/apis/query.js b/src/apis/query.js index 06228b55..1dd1e792 100644 --- a/src/apis/query.js +++ b/src/apis/query.js @@ -1,7 +1,7 @@ -import {service} from "@/utils/service"; +import { service } from '@/utils/service' export default { advancedQuery (queries) { - return service.post("/result/advanced", queries) + return service.post('/result/advanced', queries) } -} \ No newline at end of file +} diff --git a/src/apis/report.js b/src/apis/report.js index d28ecfbe..6ad193f9 100644 --- a/src/apis/report.js +++ b/src/apis/report.js @@ -1,19 +1,18 @@ -import {service} from '@/utils/service' +import { service } from '@/utils/service' import config from '@/config' import store from '@/store' -// import { v4 as uuidv4 } from 'uuid' -// IdempotencyKey export default { - async submitReport({stageId, drops}) { - return service.post("/report", { + async submitReport ({ stageId, drops }, patch) { + return service.post('/report', { drops, stageId, - server: store.getters["dataSource/server"], - ...config.api.submitParams + server: store.getters['dataSource/server'], + ...config.api.submitParams, + ...patch }) }, async recallReport (submissionId) { - return service.post("/report/recall", submissionId) + return service.post('/report/recall', submissionId) } -} \ No newline at end of file +} diff --git a/src/assets/ccIcon/by.svg b/src/assets/ccIcon/by.svg deleted file mode 100644 index 8ab2232a..00000000 --- a/src/assets/ccIcon/by.svg +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/ccIcon/cc.svg b/src/assets/ccIcon/cc.svg deleted file mode 100644 index c0721eda..00000000 --- a/src/assets/ccIcon/cc.svg +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/ccIcon/nc.svg b/src/assets/ccIcon/nc.svg deleted file mode 100644 index 7875d016..00000000 --- a/src/assets/ccIcon/nc.svg +++ /dev/null @@ -1,10 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/fonts/Bender.svg b/src/assets/fonts/Bender.svg old mode 100755 new mode 100644 diff --git a/src/assets/fonts/Bender.ttf b/src/assets/fonts/Bender.ttf old mode 100755 new mode 100644 diff --git a/src/assets/logo_clipped.png b/src/assets/logo_clipped.png deleted file mode 100644 index 5a4b76a1..00000000 Binary files a/src/assets/logo_clipped.png and /dev/null differ diff --git a/src/assets/logo_padding.png b/src/assets/logo_padding.png new file mode 100644 index 00000000..b45a6a0c Binary files /dev/null and b/src/assets/logo_padding.png differ diff --git a/src/assets/preloader-i18n-inline.js b/src/assets/preloader-i18n-inline.js index 9201f5e9..65b0fd7b 100644 --- a/src/assets/preloader-i18n-inline.js +++ b/src/assets/preloader-i18n-inline.js @@ -1,70 +1,70 @@ -"use strict"; +'use strict' -if (!Object.entries) - Object.entries = function( obj ){ - var ownProps = Object.keys( obj ), - i = ownProps.length, - resArray = new Array(i); // preallocate the Array - while (i--) - resArray[i] = [ownProps[i], obj[ownProps[i]]]; +if (!Object.entries) { + Object.entries = function (obj) { + var ownProps = Object.keys(obj) + var i = ownProps.length + var resArray = new Array(i) // preallocate the Array + while (i--) { resArray[i] = [ownProps[i], obj[ownProps[i]]] } - return resArray; - }; + return resArray + } +} -let _i18n = { +const _i18n = { languageWithRegion () { - let nav = window.navigator, - browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'], - i, - language, - len, - shortLanguage = null; + const nav = window.navigator + const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'] + let i + let language + let len + let shortLanguage = null // support for HTML 5.1 "navigator.languages" if (Array.isArray(nav.languages)) { for (i = 0; i < nav.languages.length; i++) { - language = nav.languages[i]; - len = language.length; + language = nav.languages[i] + len = language.length if (!shortLanguage && len) { - shortLanguage = language; + shortLanguage = language } - if (language && len>2) { - return language; + if (language && len > 2) { + return language } } } // support for other well known properties in browsers for (i = 0; i < browserLanguagePropertyKeys.length; i++) { - language = nav[browserLanguagePropertyKeys[i]]; - //skip this loop iteration if property is null/undefined. IE11 fix. - if (language == null) { continue; } - len = language.length; + language = nav[browserLanguagePropertyKeys[i]] + // skip this loop iteration if property is null/undefined. IE11 fix. + if (language == null) { continue } + len = language.length if (!shortLanguage && len) { - shortLanguage = language; + shortLanguage = language } if (language && len > 2) { - return language; + return language } } - return shortLanguage; + return shortLanguage }, language () { if (localStorage) { - const settings = localStorage.getItem("penguin-stats-settings") + const settings = localStorage.getItem('penguin-stats-settings') if (settings) { try { - const data = JSON.parse(settings); + const data = JSON.parse(settings) return data.settings.language } catch (e) { // fallback } } } - const language = this.languageWithRegion().replace("_", "-"); - if (!language) return "en"; // use default - const languages = language.split("-"); + const language = this.languageWithRegion().replace('_', '-') + if (!language) return 'en' // use default + const languages = language.split('-') if (languages.length === 1) { return language } else if (languages.length === 2) { @@ -75,39 +75,39 @@ let _i18n = { } }, data: { - "en": { - "load_title--text": "Loading", - "load_caption--text": "Initialization may take some time", - "load_copyright--text": "Penguin Statistics" - }, - "ja": { - "load_title--text": "読み込み中...", - "load_caption--text": "初めての読み込みは動作が遅くなる可能性があります
少々お待ち下さい", - "load_copyright--text": "ペンギン急便データ統計処理部門" + en: { + 'load_title--text': 'Loading', + 'load_caption--text': 'Initialization may take some time', + 'load_copyright--text': 'Penguin Statistics' }, - "ko": { - "load_title--text": "로딩중...", - "load_caption--text": "초기 설정에 시간이 좀 걸릴 수 있으니, 기다려 주시기 바랍니다", - "load_copyright--text": "펭귄 물류 데이터 분석 부서" + ja: { + 'load_title--text': '読み込み中...', + 'load_caption--text': '初めての読み込みは動作が遅くなる可能性があります
少々お待ち下さい', + 'load_copyright--text': 'ペンギン急便データ統計処理部門' }, + ko: { + 'load_title--text': '로딩중...', + 'load_caption--text': '초기 설정에 시간이 좀 걸릴 수 있으니, 기다려 주시기 바랍니다', + 'load_copyright--text': '펭귄 물류 데이터 분석 부서' + } }, fill (key, content) { - document.querySelector("#" + key).innerHTML = content; + document.querySelector('#' + key).innerHTML = content }, render () { - document.querySelector("#load_copyright_year--text").textContent = new Date().getFullYear().toString(); - let language = this.language(); - if (language in this.data && typeof language === "string" && language.length <= 2) { - let messages = this.data[language]; - for (let [key, value] of Object.entries(messages)) { + document.querySelector('#load_copyright_year--text').textContent = new Date().getFullYear().toString() + const language = this.language() + if (language in this.data && typeof language === 'string' && language.length <= 2) { + const messages = this.data[language] + for (const [key, value] of Object.entries(messages)) { this.fill(key, value) } } } -}; +} try { _i18n.render() } catch (e) { console.error(e) -} \ No newline at end of file +} diff --git a/src/assets/qrcodes/logos.svg b/src/assets/qrcodes/logos.svg deleted file mode 100644 index 5066c4d7..00000000 --- a/src/assets/qrcodes/logos.svg +++ /dev/null @@ -1,12 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/themes/new-year/landscape.jpg b/src/assets/themes/new-year/landscape.jpg new file mode 100644 index 00000000..9646c860 Binary files /dev/null and b/src/assets/themes/new-year/landscape.jpg differ diff --git a/src/assets/themes/new-year/portrait.jpg b/src/assets/themes/new-year/portrait.jpg new file mode 100644 index 00000000..9731924e Binary files /dev/null and b/src/assets/themes/new-year/portrait.jpg differ diff --git a/src/assets/under-deploy-i18n-inline.js b/src/assets/under-deploy-i18n-inline.js index 4a415d73..4a0b54c1 100644 --- a/src/assets/under-deploy-i18n-inline.js +++ b/src/assets/under-deploy-i18n-inline.js @@ -1,48 +1,48 @@ -"use strict"; +'use strict' -let _i18n = { +const _i18n = { getFirstBrowserLanguageWithRegionCode () { - let nav = window.navigator, - browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'], - i, - language, - len, - shortLanguage = null; + const nav = window.navigator + const browserLanguagePropertyKeys = ['language', 'browserLanguage', 'systemLanguage', 'userLanguage'] + let i + let language + let len + let shortLanguage = null // support for HTML 5.1 "navigator.languages" if (Array.isArray(nav.languages)) { for (i = 0; i < nav.languages.length; i++) { - language = nav.languages[i]; - len = language.length; + language = nav.languages[i] + len = language.length if (!shortLanguage && len) { - shortLanguage = language; + shortLanguage = language } - if (language && len>2) { - return language; + if (language && len > 2) { + return language } } } // support for other well known properties in browsers for (i = 0; i < browserLanguagePropertyKeys.length; i++) { - language = nav[browserLanguagePropertyKeys[i]]; - //skip this loop iteration if property is null/undefined. IE11 fix. - if (language == null) { continue; } - len = language.length; + language = nav[browserLanguagePropertyKeys[i]] + // skip this loop iteration if property is null/undefined. IE11 fix. + if (language == null) { continue } + len = language.length if (!shortLanguage && len) { - shortLanguage = language; + shortLanguage = language } if (language && len > 2) { - return language; + return language } } - return shortLanguage; + return shortLanguage }, getFirstBrowserLanguage () { - const language = this.getFirstBrowserLanguageWithRegionCode().replace("_", "-"); - if (!language) return "zh"; // use default - const languages = language.split("-"); + const language = this.getFirstBrowserLanguageWithRegionCode().replace('_', '-') + if (!language) return 'zh' // use default + const languages = language.split('-') if (languages.length === 1) { return language } else if (languages.length === 2) { @@ -53,39 +53,39 @@ let _i18n = { } }, data: { - "en": { - "deploy_title--text": "Deploying", - "deploy_caption--text": "Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.", - "deploy_copyright--text": "Penguin Statistics" + en: { + 'deploy_title--text': 'Deploying', + 'deploy_caption--text': 'Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.', + 'deploy_copyright--text': 'Penguin Statistics' }, - "ja": { - "deploy_title--text": "Deploying", - "deploy_caption--text": "Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.", - "deploy_copyright--text": "Penguin Statistics" - }, - "ko": { - "deploy_title--text": "Deploying", - "deploy_caption--text": "Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.", - "deploy_copyright--text": "Penguin Statistics" + ja: { + 'deploy_title--text': 'Deploying', + 'deploy_caption--text': 'Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.', + 'deploy_copyright--text': 'Penguin Statistics' }, + ko: { + 'deploy_title--text': 'Deploying', + 'deploy_caption--text': 'Deployment may last up to 5 minutes.
After the deployment, the page will automatically refresh. Please wait.', + 'deploy_copyright--text': 'Penguin Statistics' + } }, fill (key, content) { - document.querySelector("#" + key).innerHTML = content; + document.querySelector('#' + key).innerHTML = content }, render () { - document.querySelector("#deploy_copyright_year--text").textContent = new Date().getFullYear().toString(); - let language = this.getFirstBrowserLanguage(); - if (language in this.data && typeof language === "string" && language.length <= 2) { - let messages = this.data[language]; - for (let [key, value] of Object.entries(messages)) { + document.querySelector('#deploy_copyright_year--text').textContent = new Date().getFullYear().toString() + const language = this.getFirstBrowserLanguage() + if (language in this.data && typeof language === 'string' && language.length <= 2) { + const messages = this.data[language] + for (const [key, value] of Object.entries(messages)) { this.fill(key, value) } } } -}; +} try { _i18n.render() } catch (e) { console.error(e) -} \ No newline at end of file +} diff --git a/src/assets/under-deploy.html b/src/assets/under-deploy.html index e226ed40..61c740f8 100644 --- a/src/assets/under-deploy.html +++ b/src/assets/under-deploy.html @@ -237,7 +237,7 @@ 新版本部署最多将持续5分钟
部署完成后页面将自动刷新。请耐心等待。
\ No newline at end of file + diff --git a/src/components/advancedQuery/QueryMain.vue b/src/components/advancedQuery/QueryMain.vue index 8fd1af53..ffb158cd 100644 --- a/src/components/advancedQuery/QueryMain.vue +++ b/src/components/advancedQuery/QueryMain.vue @@ -53,96 +53,96 @@ \ No newline at end of file + diff --git a/src/components/advancedQuery/QueryResult.vue b/src/components/advancedQuery/QueryResult.vue index 055cdfd2..9615611b 100644 --- a/src/components/advancedQuery/QueryResult.vue +++ b/src/components/advancedQuery/QueryResult.vue @@ -33,73 +33,73 @@ \ No newline at end of file + diff --git a/src/components/advancedQuery/QueryResultTrend.vue b/src/components/advancedQuery/QueryResultTrend.vue index fa2f80ef..41d52bc7 100644 --- a/src/components/advancedQuery/QueryResultTrend.vue +++ b/src/components/advancedQuery/QueryResultTrend.vue @@ -8,7 +8,7 @@ :label="$t('query.result.hideTime')" class="mx-2 mt-6 mb-0" /> - + - \ No newline at end of file + diff --git a/src/components/advancedQuery/selectors/MultiItemSelector.vue b/src/components/advancedQuery/selectors/MultiItemSelector.vue index 1b0c56c8..55795c4d 100644 --- a/src/components/advancedQuery/selectors/MultiItemSelector.vue +++ b/src/components/advancedQuery/selectors/MultiItemSelector.vue @@ -45,54 +45,54 @@ \ No newline at end of file + diff --git a/src/components/advancedQuery/selectors/QuerySelectorInterval.vue b/src/components/advancedQuery/selectors/QuerySelectorInterval.vue index 5991a01a..ac21c086 100644 --- a/src/components/advancedQuery/selectors/QuerySelectorInterval.vue +++ b/src/components/advancedQuery/selectors/QuerySelectorInterval.vue @@ -13,7 +13,7 @@ @input="update" > -